Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 1509 | Ganze Datei anzeigen | Leerzeichen ignorieren | Details | Blame | Letzte Änderung | Log anzeigen | RSS feed

Revision 1509 Revision 1551
Zeile 1... Zeile 1...
1
/*
1
/*
2
 * jQuery File Upload Plugin 5.2
2
 * jQuery File Upload Plugin
3
 * https://github.com/blueimp/jQuery-File-Upload
3
 * https://github.com/blueimp/jQuery-File-Upload
4
 *
4
 *
5
 * Copyright 2010, Sebastian Tschan
5
 * Copyright 2010, Sebastian Tschan
6
 * https://blueimp.net
6
 * https://blueimp.net
7
 *
7
 *
8
 * Licensed under the MIT license:
8
 * Licensed under the MIT license:
9
 * http://creativecommons.org/licenses/MIT/
9
 * https://opensource.org/licenses/MIT
10
 */
10
 */
Zeile 11... Zeile 11...
11
 
11
 
12
/*jslint nomen: true, unparam: true, regexp: true */
12
/* global define, require */
Zeile -... Zeile 197...
-
 
197
        return message;
-
 
198
      },
-
 
199
 
-
 
200
      // Additional form data to be sent along with the file uploads can be set
-
 
201
      // using this option, which accepts an array of objects with name and
165
            return [];
202
      // value properties, a function returning such an array, a FormData
-
 
203
      // object (for XHR file uploads), or a simple object.
-
 
204
      // The form of the first fileInput is given as parameter to the function:
-
 
205
      formData: function (form) {
-
 
206
        return form.serializeArray();
-
 
207
      },
-
 
208
 
-
 
209
      // The add callback is invoked as soon as files are added to the fileupload
-
 
210
      // widget (via file input selection, drag & drop, paste or add API call).
-
 
211
      // If the singleFileUploads option is enabled, this callback will be
-
 
212
      // called once for each file in the selection for XHR file uploads, else
-
 
213
      // once for each file selection.
-
 
214
      //
-
 
215
      // The upload starts when the submit method is invoked on the data parameter.
-
 
216
      // The data object contains a files property holding the added files
-
 
217
      // and allows you to override plugin options as well as define ajax settings.
-
 
218
      //
-
 
219
      // Listeners for this callback can also be bound the following way:
-
 
220
      // .on('fileuploadadd', func);
-
 
221
      //
-
 
222
      // data.submit() returns a Promise object and allows to attach additional
-
 
223
      // handlers using jQuery's Deferred callbacks:
166
        },
224
      // data.submit().done(func).fail(func).always(func);
-
 
225
      add: function (e, data) {
-
 
226
        if (e.isDefaultPrevented()) {
167
 
227
          return false;
168
        _getTotal: function (files) {
228
        }
-
 
229
        if (
169
            var total = 0;
230
          data.autoUpload ||
-
 
231
          (data.autoUpload !== false &&
170
            $.each(files, function (index, file) {
232
            $(this).fileupload('option', 'autoUpload'))
-
 
233
        ) {
171
                total += file.size || 1;
234
          data.process().done(function () {
-
 
235
            data.submit();
Zeile 172... Zeile -...
172
            });
-
 
173
            return total;
-
 
174
        },
-
 
175
 
-
 
176
        _onProgress: function (e, data) {
-
 
177
            if (e.lengthComputable) {
236
          });
178
                var total = data.total || this._getTotal(data.files),
-
 
179
                    loaded = parseInt(
-
 
180
                        e.loaded / e.total * (data.chunkSize || total),
-
 
181
                        10
-
 
182
                    ) + (data.uploadedBytes || 0);
-
 
183
                this._loaded += loaded - (data.loaded || data.uploadedBytes || 0);
-
 
184
                data.lengthComputable = true;
-
 
185
                data.loaded = loaded;
-
 
186
                data.total = total;
-
 
187
                // Trigger a custom progress event with a total data property set
-
 
188
                // to the file size(s) of the current upload and a loaded data
-
 
189
                // property calculated accordingly:
-
 
190
                this._trigger('progress', e, data);
-
 
191
                // Trigger a global progress event for all current file uploads,
-
 
192
                // including ajax calls queued for sequential file uploads:
-
 
193
                this._trigger('progressall', e, {
-
 
194
                    lengthComputable: true,
-
 
195
                    loaded: this._loaded,
-
 
Zeile 196... Zeile -...
196
                    total: this._total
-
 
197
                });
-
 
198
            }
-
 
199
        },
-
 
200
 
237
        }
201
        _initProgressListener: function (options) {
-
 
202
            var that = this,
238
      },
203
                xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
-
 
204
            // Accesss to the native XHR object is required to add event listeners
-
 
205
            // for the upload progress event:
-
 
206
            if (xhr.upload && xhr.upload.addEventListener) {
-
 
207
                xhr.upload.addEventListener('progress', function (e) {
-
 
208
                    that._onProgress(e, options);
-
 
209
                }, false);
-
 
Zeile 276... Zeile 575...
276
            if (this._isXHRUpload(options)) {
575
                var fileName = file.uploadName || file.name;
-
 
576
                if (options.uniqueFilenames) {
-
 
577
                  fileName = that._getUniqueFilename(
-
 
578
                    fileName,
-
 
579
                    options.uniqueFilenames
-
 
580
                  );
-
 
581
                }
-
 
582
                formData.append(
-
 
583
                  ($.type(options.paramName) === 'array' &&
-
 
584
                    options.paramName[index]) ||
-
 
585
                    paramName,
-
 
586
                  file,
-
 
587
                  fileName
-
 
588
                );
-
 
589
              }
-
 
590
            });
-
 
591
          }
-
 
592
        }
-
 
593
        options.data = formData;
-
 
594
      }
-
 
595
      // Blob reference is not needed anymore, free memory:
-
 
596
      options.blob = null;
-
 
597
    },
-
 
598
 
-
 
599
    _initIframeSettings: function (options) {
-
 
600
      var targetHost = $('<a></a>').prop('href', options.url).prop('host');
-
 
601
      // Setting the dataType to iframe enables the iframe transport:
-
 
602
      options.dataType = 'iframe ' + (options.dataType || '');
-
 
603
      // The iframe transport accepts a serialized array as form data:
-
 
604
      options.formData = this._getFormData(options);
-
 
605
      // Add redirect url to form data on cross-domain uploads:
-
 
606
      if (options.redirect && targetHost && targetHost !== location.host) {
-
 
607
        options.formData.push({
-
 
608
          name: options.redirectParamName || 'redirect',
-
 
609
          value: options.redirect
-
 
610
        });
-
 
611
      }
-
 
612
    },
-
 
613
 
-
 
614
    _initDataSettings: function (options) {
-
 
615
      if (this._isXHRUpload(options)) {
-
 
616
        if (!this._chunkedUpload(options, true)) {
-
 
617
          if (!options.data) {
-
 
618
            this._initXHRData(options);
-
 
619
          }
-
 
620
          this._initProgressListener(options);
-
 
621
        }
-
 
622
        if (options.postMessage) {
-
 
623
          // Setting the dataType to postmessage enables the
-
 
624
          // postMessage transport:
-
 
625
          options.dataType = 'postmessage ' + (options.dataType || '');
-
 
626
        }
-
 
627
      } else {
-
 
628
        this._initIframeSettings(options);
-
 
629
      }
-
 
630
    },
-
 
631
 
-
 
632
    _getParamName: function (options) {
-
 
633
      var fileInput = $(options.fileInput),
-
 
634
        paramName = options.paramName;
-
 
635
      if (!paramName) {
-
 
636
        paramName = [];
-
 
637
        fileInput.each(function () {
-
 
638
          var input = $(this),
-
 
639
            name = input.prop('name') || 'files[]',
-
 
640
            i = (input.prop('files') || [1]).length;
-
 
641
          while (i) {
-
 
642
            paramName.push(name);
-
 
643
            i -= 1;
-
 
644
          }
-
 
645
        });
-
 
646
        if (!paramName.length) {
-
 
647
          paramName = [fileInput.prop('name') || 'files[]'];
-
 
648
        }
-
 
649
      } else if (!$.isArray(paramName)) {
-
 
650
        paramName = [paramName];
-
 
651
      }
-
 
652
      return paramName;
-
 
653
    },
-
 
654
 
-
 
655
    _initFormSettings: function (options) {
-
 
656
      // Retrieve missing options from the input field and the
-
 
657
      // associated form, if available:
-
 
658
      if (!options.form || !options.form.length) {
-
 
659
        options.form = $(options.fileInput.prop('form'));
-
 
660
        // If the given file input doesn't have an associated form,
-
 
661
        // use the default widget file input's form:
-
 
662
        if (!options.form.length) {
-
 
663
          options.form = $(this.options.fileInput.prop('form'));
-
 
664
        }
-
 
665
      }
-
 
666
      options.paramName = this._getParamName(options);
-
 
667
      if (!options.url) {
-
 
668
        options.url = options.form.prop('action') || location.href;
-
 
669
      }
-
 
670
      // The HTTP request method must be "POST" or "PUT":
-
 
671
      options.type = (
-
 
672
        options.type ||
-
 
673
        ($.type(options.form.prop('method')) === 'string' &&
-
 
674
          options.form.prop('method')) ||
-
 
675
        ''
-
 
676
      ).toUpperCase();
-
 
677
      if (
-
 
678
        options.type !== 'POST' &&
-
 
679
        options.type !== 'PUT' &&
-
 
680
        options.type !== 'PATCH'
-
 
681
      ) {
-
 
682
        options.type = 'POST';
-
 
683
      }
-
 
684
      if (!options.formAcceptCharset) {
-
 
685
        options.formAcceptCharset = options.form.attr('accept-charset');
-
 
686
      }
-
 
687
    },
-
 
688
 
-
 
689
    _getAJAXSettings: function (data) {
-
 
690
      var options = $.extend({}, this.options, data);
-
 
691
      this._initFormSettings(options);
-
 
692
      this._initDataSettings(options);
-
 
693
      return options;
-
 
694
    },
-
 
695
 
-
 
696
    // jQuery 1.6 doesn't provide .state(),
-
 
697
    // while jQuery 1.8+ removed .isRejected() and .isResolved():
-
 
698
    _getDeferredState: function (deferred) {
-
 
699
      if (deferred.state) {
-
 
700
        return deferred.state();
-
 
701
      }
-
 
702
      if (deferred.isResolved()) {
-
 
703
        return 'resolved';
-
 
704
      }
-
 
705
      if (deferred.isRejected()) {
-
 
706
        return 'rejected';
-
 
707
      }
-
 
708
      return 'pending';
-
 
709
    },
-
 
710
 
-
 
711
    // Maps jqXHR callbacks to the equivalent
-
 
712
    // methods of the given Promise object:
-
 
713
    _enhancePromise: function (promise) {
-
 
714
      promise.success = promise.done;
-
 
715
      promise.error = promise.fail;
-
 
716
      promise.complete = promise.always;
-
 
717
      return promise;
-
 
718
    },
-
 
719
 
-
 
720
    // Creates and returns a Promise object enhanced with
-
 
721
    // the jqXHR methods abort, success, error and complete:
-
 
722
    _getXHRPromise: function (resolveOrReject, context, args) {
-
 
723
      var dfd = $.Deferred(),
-
 
724
        promise = dfd.promise();
-
 
725
      // eslint-disable-next-line no-param-reassign
-
 
726
      context = context || this.options.context || promise;
-
 
727
      if (resolveOrReject === true) {
-
 
728
        dfd.resolveWith(context, args);
-
 
729
      } else if (resolveOrReject === false) {
-
 
730
        dfd.rejectWith(context, args);
-
 
731
      }
-
 
732
      promise.abort = dfd.promise;
-
 
733
      return this._enhancePromise(promise);
-
 
734
    },
-
 
735
 
-
 
736
    // Adds convenience methods to the data callback argument:
-
 
737
    _addConvenienceMethods: function (e, data) {
-
 
738
      var that = this,
-
 
739
        getPromise = function (args) {
-
 
740
          return $.Deferred().resolveWith(that, args).promise();
-
 
741
        };
-
 
742
      data.process = function (resolveFunc, rejectFunc) {
-
 
743
        if (resolveFunc || rejectFunc) {
-
 
744
          data._processQueue = this._processQueue = (this._processQueue ||
-
 
745
            getPromise([this]))
-
 
746
            [that._promisePipe](function () {
-
 
747
              if (data.errorThrown) {
-
 
748
                return $.Deferred().rejectWith(that, [data]).promise();
-
 
749
              }
-
 
750
              return getPromise(arguments);
-
 
751
            })
-
 
752
            [that._promisePipe](resolveFunc, rejectFunc);
-
 
753
        }
-
 
754
        return this._processQueue || getPromise([this]);
-
 
755
      };
-
 
756
      data.submit = function () {
-
 
757
        if (this.state() !== 'pending') {
-
 
758
          data.jqXHR = this.jqXHR =
-
 
759
            that._trigger(
-
 
760
              'submit',
-
 
761
              $.Event('submit', { delegatedEvent: e }),
-
 
762
              this
-
 
763
            ) !== false && that._onSend(e, this);
-
 
764
        }
-
 
765
        return this.jqXHR || that._getXHRPromise();
-
 
766
      };
-
 
767
      data.abort = function () {
-
 
768
        if (this.jqXHR) {
-
 
769
          return this.jqXHR.abort();
-
 
770
        }
-
 
771
        this.errorThrown = 'abort';
-
 
772
        that._trigger('fail', null, this);
-
 
773
        return that._getXHRPromise(false);
-
 
774
      };
-
 
775
      data.state = function () {
-
 
776
        if (this.jqXHR) {
-
 
777
          return that._getDeferredState(this.jqXHR);
-
 
778
        }
-
 
779
        if (this._processQueue) {
-
 
780
          return that._getDeferredState(this._processQueue);
-
 
781
        }
-
 
782
      };
-
 
783
      data.processing = function () {
-
 
784
        return (
-
 
785
          !this.jqXHR &&
-
 
786
          this._processQueue &&
-
 
787
          that._getDeferredState(this._processQueue) === 'pending'
-
 
788
        );
-
 
789
      };
-
 
790
      data.progress = function () {
-
 
791
        return this._progress;
-
 
792
      };
-
 
793
      data.response = function () {
-
 
794
        return this._response;
-
 
795
      };
-
 
796
    },
-
 
797
 
-
 
798
    // Parses the Range header from the server response
-
 
799
    // and returns the uploaded bytes:
-
 
800
    _getUploadedBytes: function (jqXHR) {
-
 
801
      var range = jqXHR.getResponseHeader('Range'),
-
 
802
        parts = range && range.split('-'),
-
 
803
        upperBytesPos = parts && parts.length > 1 && parseInt(parts[1], 10);
-
 
804
      return upperBytesPos && upperBytesPos + 1;
-
 
805
    },
-
 
806
 
-
 
807
    // Uploads a file in multiple, sequential requests
-
 
808
    // by splitting the file up in multiple blob chunks.
-
 
809
    // If the second parameter is true, only tests if the file
-
 
810
    // should be uploaded in chunks, but does not invoke any
-
 
811
    // upload requests:
-
 
812
    _chunkedUpload: function (options, testOnly) {
-
 
813
      options.uploadedBytes = options.uploadedBytes || 0;
-
 
814
      var that = this,
-
 
815
        file = options.files[0],
-
 
816
        fs = file.size,
-
 
817
        ub = options.uploadedBytes,
-
 
818
        mcs = options.maxChunkSize || fs,
-
 
819
        slice = this._blobSlice,
-
 
820
        dfd = $.Deferred(),
-
 
821
        promise = dfd.promise(),
-
 
822
        jqXHR,
-
 
823
        upload;
-
 
824
      if (
-
 
825
        !(
-
 
826
          this._isXHRUpload(options) &&
-
 
827
          slice &&
-
 
828
          (ub || ($.type(mcs) === 'function' ? mcs(options) : mcs) < fs)
-
 
829
        ) ||
-
 
830
        options.data
-
 
831
      ) {
-
 
832
        return false;
-
 
833
      }
-
 
834
      if (testOnly) {
-
 
835
        return true;
-
 
836
      }
-
 
837
      if (ub >= fs) {
-
 
838
        file.error = options.i18n('uploadedBytes');
-
 
839
        return this._getXHRPromise(false, options.context, [
-
 
840
          null,
-
 
841
          'error',
-
 
842
          file.error
-
 
843
        ]);
-
 
844
      }
-
 
845
      // The chunk upload method:
-
 
846
      upload = function () {
-
 
847
        // Clone the options object for each chunk upload:
-
 
848
        var o = $.extend({}, options),
-
 
849
          currentLoaded = o._progress.loaded;
-
 
850
        o.blob = slice.call(
-
 
851
          file,
-
 
852
          ub,
-
 
853
          ub + ($.type(mcs) === 'function' ? mcs(o) : mcs),
-
 
854
          file.type
-
 
855
        );
-
 
856
        // Store the current chunk size, as the blob itself
-
 
857
        // will be dereferenced after data processing:
-
 
858
        o.chunkSize = o.blob.size;
-
 
859
        // Expose the chunk bytes position range:
-
 
860
        o.contentRange =
-
 
861
          'bytes ' + ub + '-' + (ub + o.chunkSize - 1) + '/' + fs;
-
 
862
        // Trigger chunkbeforesend to allow form data to be updated for this chunk
-
 
863
        that._trigger('chunkbeforesend', null, o);
-
 
864
        // Process the upload data (the blob and potential form data):
-
 
865
        that._initXHRData(o);
-
 
866
        // Add progress listeners for this chunk upload:
-
 
867
        that._initProgressListener(o);
-
 
868
        jqXHR = (
-
 
869
          (that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||
-
 
870
          that._getXHRPromise(false, o.context)
-
 
871
        )
-
 
872
          .done(function (result, textStatus, jqXHR) {
-
 
873
            ub = that._getUploadedBytes(jqXHR) || ub + o.chunkSize;
-
 
874
            // Create a progress event if no final progress event
-
 
875
            // with loaded equaling total has been triggered
-
 
876
            // for this chunk:
-
 
877
            if (currentLoaded + o.chunkSize - o._progress.loaded) {
-
 
878
              that._onProgress(
-
 
879
                $.Event('progress', {
-
 
880
                  lengthComputable: true,
-
 
881
                  loaded: ub - o.uploadedBytes,
-
 
882
                  total: ub - o.uploadedBytes
-
 
883
                }),
-
 
884
                o
-
 
885
              );
-
 
886
            }
-
 
887
            options.uploadedBytes = o.uploadedBytes = ub;
-
 
888
            o.result = result;
-
 
889
            o.textStatus = textStatus;
-
 
890
            o.jqXHR = jqXHR;
277
                if (!this._chunkedUpload(options, true)) {
891
            that._trigger('chunkdone', null, o);
278
                    if (!options.data) {
-
 
279
                        this._initXHRData(options);
-
 
280
                    }
-
 
281
                    this._initProgressListener(options);
-
 
282
                }
-
 
283
            } else {
892
            that._trigger('chunkalways', null, o);
284
                this._initIframeSettings(options);
-
 
285
            }
-
 
286
        },
-
 
287
        
-
 
288
        _initFormSettings: function (options) {
-
 
289
            // Retrieve missing options from the input field and the
-
 
290
            // associated form, if available:
-
 
291
            if (!options.form || !options.form.length) {
893
            if (ub < fs) {
532
                    var args = [undefined, 'abort', 'abort'];
1036
                  // that has not been aborted:
533
                    if (!jqXHR) {
1037
                  var nextSlot = that._slots.shift();
534
                        if (slot) {
1038
                  while (nextSlot) {
535
                            slot.rejectWith(args);
-
 
536
                        }
-
 
537
                        return send(false, args);
-
 
538
                    }
-
 
539
                    return jqXHR.abort();
-
 
540
                };
-
 
541
                return this._enhancePromise(pipe);
-
 
542
            }
-
 
543
            return send();
-
 
544
        },
-
 
545
        
-
 
546
        _onAdd: function (e, data) {
-
 
547
            var that = this,
-
 
548
                result = true,
-
 
549
                options = $.extend({}, this.options, data),
-
 
550
                fileSet = data.files,
-
 
551
                limit = options.limitMultiFileUploads,
-
 
552
                i;
-
 
553
            if (!(options.singleFileUploads || limit) ||
-
 
554
                    !this._isXHRUpload(options)) {
1039
                    if (that._getDeferredState(nextSlot) === 'pending') {
555
                fileSet = [fileSet];
-
 
556
            } else if (!options.singleFileUploads && limit) {
-
 
557
                fileSet = [];
-
 
558
                for (i = 0; i < data.files.length; i += limit) {
-
 
559
                    fileSet.push(data.files.slice(i, i + limit));
1040
                      nextSlot.resolve();
560
                }
-
 
561
            }
-
 
562
            $.each(fileSet, function (index, file) {
1041
                      break;
563
                var files = $.isArray(file) ? file : [file],
-
 
564
                    newData = $.extend({}, data, {files: files});
-
 
565
                newData.submit = function () {
-
 
566
                    return that._onSend(e, newData);
-
 
567
                };
-
 
568
                return (result = that._trigger('add', e, newData));
-
 
569
            });
-
 
570
            return result;
-
 
571
        },
-
 
572
        
-
 
573
        // File Normalization for Gecko 1.9.1 (Firefox 3.5) support:
-
 
574
        _normalizeFile: function (index, file) {
-
 
575
            if (file.name === undefined && file.size === undefined) {
-
 
576
                file.name = file.fileName;
-
 
577
                file.size = file.fileSize;
-
 
578
            }
-
 
579
        },
-
 
580
 
-
 
581
        _replaceFileInput: function (input) {
1042
                    }
582
            var inputClone = input.clone(true);
-
 
583
            $('<form></form>').append(inputClone)[0].reset();
-
 
584
            // Detaching allows to insert the fileInput on another form
-
 
585
            // without loosing the file input value:
-
 
586
            input.after(inputClone).detach();
1043
                    nextSlot = that._slots.shift();
587
            // Replace the original file input element in the fileInput
1044
                  }
588
            // collection with the clone, which has been copied including
1045
                }
589
            // event handlers:
1046
                if (that._active === 0) {
590
            this.options.fileInput = this.options.fileInput.map(function (i, el) {
1047
                  // The stop callback is triggered when all uploads have
-
 
1048
                  // been completed, equivalent to the global ajaxStop event:
591
                if (el === input[0]) {
1049
                  that._trigger('stop');
592
                    return inputClone[0];
1050
                }
593
                }
1051
              });
-
 
1052
          return jqXHR;
594
                return el;
1053
        };
595
            });
1054
      this._beforeSend(e, options);
-
 
1055
      if (
596
        },
1056
        this.options.sequentialUploads ||
597
        
1057
        (this.options.limitConcurrentUploads &&
598
        _onChange: function (e) {
1058
          this.options.limitConcurrentUploads <= this._sending)
-
 
1059
      ) {
599
            var that = e.data.fileupload,
1060
        if (this.options.limitConcurrentUploads > 1) {
-
 
1061
          slot = $.Deferred();
600
                data = {
1062
          this._slots.push(slot);
601
                    files: $.each($.makeArray(e.target.files), that._normalizeFile),
1063
          pipe = slot[that._promisePipe](send);
602
                    fileInput: $(e.target),
1064
        } else {
-
 
1065
          this._sequence = this._sequence[that._promisePipe](send, send);
-
 
1066
          pipe = this._sequence;
-
 
1067
        }
-
 
1068
        // Return the piped Promise object, enhanced with an abort method,
603
                    form: $(e.target.form)
1069
        // which is delegated to the jqXHR object of the current upload,
604
                };
1070
        // and jqXHR callbacks mapped to the equivalent Promise methods:
-
 
1071
        pipe.abort = function () {
-
 
1072
          aborted = [undefined, 'abort', 'abort'];
-
 
1073
          if (!jqXHR) {
-
 
1074
            if (slot) {
-
 
1075
              slot.rejectWith(options.context, aborted);
-
 
1076
            }
-
 
1077
            return send();
-
 
1078
          }
-
 
1079
          return jqXHR.abort();
-
 
1080
        };
-
 
1081
        return this._enhancePromise(pipe);
-
 
1082
      }
-
 
1083
      return send();
-
 
1084
    },
-
 
1085
 
-
 
1086
    _onAdd: function (e, data) {
-
 
1087
      var that = this,
-
 
1088
        result = true,
-
 
1089
        options = $.extend({}, this.options, data),
-
 
1090
        files = data.files,
-
 
1091
        filesLength = files.length,
-
 
1092
        limit = options.limitMultiFileUploads,
-
 
1093
        limitSize = options.limitMultiFileUploadSize,
-
 
1094
        overhead = options.limitMultiFileUploadSizeOverhead,
-
 
1095
        batchSize = 0,
-
 
1096
        paramName = this._getParamName(options),
-
 
1097
        paramNameSet,
-
 
1098
        paramNameSlice,
-
 
1099
        fileSet,
-
 
1100
        i,
-
 
1101
        j = 0;
-
 
1102
      if (!filesLength) {
-
 
1103
        return false;
-
 
1104
      }
-
 
1105
      if (limitSize && files[0].size === undefined) {
-
 
1106
        limitSize = undefined;
-
 
1107
      }
-
 
1108
      if (
-
 
1109
        !(options.singleFileUploads || limit || limitSize) ||
-
 
1110
        !this._isXHRUpload(options)
-
 
1111
      ) {
-
 
1112
        fileSet = [files];
-
 
1113
        paramNameSet = [paramName];
-
 
1114
      } else if (!(options.singleFileUploads || limitSize) && limit) {
-
 
1115
        fileSet = [];
-
 
1116
        paramNameSet = [];
-
 
1117
        for (i = 0; i < filesLength; i += limit) {
-
 
1118
          fileSet.push(files.slice(i, i + limit));
-
 
1119
          paramNameSlice = paramName.slice(i, i + limit);
-
 
1120
          if (!paramNameSlice.length) {
-
 
1121
            paramNameSlice = paramName;
-
 
1122
          }
-
 
1123
          paramNameSet.push(paramNameSlice);
-
 
1124
        }
-
 
1125
      } else if (!options.singleFileUploads && limitSize) {
-
 
1126
        fileSet = [];
-
 
1127
        paramNameSet = [];
-
 
1128
        for (i = 0; i < filesLength; i = i + 1) {
-
 
1129
          batchSize += files[i].size + overhead;
-
 
1130
          if (
-
 
1131
            i + 1 === filesLength ||
-
 
1132
            batchSize + files[i + 1].size + overhead > limitSize ||
-
 
1133
            (limit && i + 1 - j >= limit)
-
 
1134
          ) {
-
 
1135
            fileSet.push(files.slice(j, i + 1));
-
 
1136
            paramNameSlice = paramName.slice(j, i + 1);
-
 
1137
            if (!paramNameSlice.length) {
-
 
1138
              paramNameSlice = paramName;
-
 
1139
            }
-
 
1140
            paramNameSet.push(paramNameSlice);
-
 
1141
            j = i + 1;
-
 
1142
            batchSize = 0;
-
 
1143
          }
-
 
1144
        }
-
 
1145
      } else {
-
 
1146
        paramNameSet = paramName;
-
 
1147
      }
-
 
1148
      data.originalFiles = files;
-
 
1149
      $.each(fileSet || files, function (index, element) {
-
 
1150
        var newData = $.extend({}, data);
-
 
1151
        newData.files = fileSet ? element : [element];
-
 
1152
        newData.paramName = paramNameSet[index];
-
 
1153
        that._initResponseObject(newData);
-
 
1154
        that._initProgressObject(newData);
-
 
1155
        that._addConvenienceMethods(e, newData);
-
 
1156
        result = that._trigger(
-
 
1157
          'add',
-
 
1158
          $.Event('add', { delegatedEvent: e }),
-
 
1159
          newData
-
 
1160
        );
-
 
1161
        return result;
-
 
1162
      });
-
 
1163
      return result;
605
            if (!data.files.length) {
1164
    },
-
 
1165
 
-
 
1166
    _replaceFileInput: function (data) {
-
 
1167
      var input = data.fileInput,
-
 
1168
        inputClone = input.clone(true),
-
 
1169
        restoreFocus = input.is(document.activeElement);
-
 
1170
      // Add a reference for the new cloned file input to the data argument:
-
 
1171
      data.fileInputClone = inputClone;
-
 
1172
      $('<form></form>').append(inputClone)[0].reset();
-
 
1173
      // Detaching allows to insert the fileInput on another form
-
 
1174
      // without losing the file input value:
-
 
1175
      input.after(inputClone).detach();
-
 
1176
      // If the fileInput had focus before it was detached,
606
                // If the files property is not available, the browser does not
1177
      // restore focus to the inputClone.
-
 
1178
      if (restoreFocus) {
-
 
1179
        inputClone.trigger('focus');
-
 
1180
      }
-
 
1181
      // Avoid memory leaks with the detached file input:
-
 
1182
      $.cleanData(input.off('remove'));
-
 
1183
      // Replace the original file input element in the fileInput
-
 
1184
      // elements set with the clone, which has been copied including
-
 
1185
      // event handlers:
-
 
1186
      this.options.fileInput = this.options.fileInput.map(function (i, el) {
-
 
1187
        if (el === input[0]) {
-
 
1188
          return inputClone[0];
-
 
1189
        }
-
 
1190
        return el;
-
 
1191
      });
-
 
1192
      // If the widget has been initialized on the file input itself,
-
 
1193
      // override this.element with the file input clone:
-
 
1194
      if (input[0] === this.element[0]) {
-
 
1195
        this.element = inputClone;
-
 
1196
      }
-
 
1197
    },
-
 
1198
 
-
 
1199
    _handleFileTreeEntry: function (entry, path) {
-
 
1200
      var that = this,
-
 
1201
        dfd = $.Deferred(),
-
 
1202
        entries = [],
-
 
1203
        dirReader,
-
 
1204
        errorHandler = function (e) {
-
 
1205
          if (e && !e.entry) {
-
 
1206
            e.entry = entry;
-
 
1207
          }
-
 
1208
          // Since $.when returns immediately if one
-
 
1209
          // Deferred is rejected, we use resolve instead.
-
 
1210
          // This allows valid files and invalid items
-
 
1211
          // to be returned together in one set:
-
 
1212
          dfd.resolve([e]);
-
 
1213
        },
-
 
1214
        successHandler = function (entries) {
-
 
1215
          that
-
 
1216
            ._handleFileTreeEntries(entries, path + entry.name + '/')
-
 
1217
            .done(function (files) {
607
                // support the File API and we add a pseudo File object with
1218
              dfd.resolve(files);
608
                // the input value as name with path information removed:
1219
            })
609
                data.files = [{name: e.target.value.replace(/^.*\\/, '')}];
1220
            .fail(errorHandler);
610
            }
-
 
611
            // Store the form reference as jQuery data for other event handlers,
-
 
612
            // as the form property is not available after replacing the file input: 
-
 
613
            if (data.form.length) {
-
 
614
                data.fileInput.data('blueimp.fileupload.form', data.form);
-
 
615
            } else {
-
 
616
                data.form = data.fileInput.data('blueimp.fileupload.form');
-
 
617
            }
-
 
618
            if (that.options.replaceFileInput) {
-
 
619
                that._replaceFileInput(data.fileInput);
-
 
620
            }
-
 
621
            if (that._trigger('change', e, data) === false ||
-
 
622
                    that._onAdd(e, data) === false) {
-
 
623
                return false;
-
 
624
            }
-
 
625
        },
-
 
626
        
-
 
627
        _onDrop: function (e) {
1221
        },
628
            var that = e.data.fileupload,
-
 
629
                dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer,
-
 
630
                data = {
-
 
631
                    files: $.each(
-
 
632
                        $.makeArray(dataTransfer && dataTransfer.files),
1222
        readEntries = function () {
633
                        that._normalizeFile
1223
          dirReader.readEntries(function (results) {
634
                    )
1224
            if (!results.length) {
635
                };
1225
              successHandler(entries);
636
            if (that._trigger('drop', e, data) === false ||
-
 
-
 
1226
            } else {
-
 
1227
              entries = entries.concat(results);
-
 
1228
              readEntries();
637
                    that._onAdd(e, data) === false) {
1229
            }
638
                return false;
1230
          }, errorHandler);
639
            }
1231
        };
-
 
1232
      // eslint-disable-next-line no-param-reassign
-
 
1233
      path = path || '';
-
 
1234
      if (entry.isFile) {
640
            e.preventDefault();
1235
        if (entry._file) {
641
        },
1236
          // Workaround for Chrome bug #149735
-
 
1237
          entry._file.relativePath = path;
642
        
1238
          dfd.resolve(entry._file);
643
        _onDragOver: function (e) {
1239
        } else {
644
            var that = e.data.fileupload,
1240
          entry.file(function (file) {
-
 
1241
            file.relativePath = path;
645
                dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer;
1242
            dfd.resolve(file);
-
 
1243
          }, errorHandler);
-
 
1244
        }
646
            if (that._trigger('dragover', e) === false) {
1245
      } else if (entry.isDirectory) {
647
                return false;
1246
        dirReader = entry.createReader();
-
 
1247
        readEntries();
-
 
1248
      } else {
648
            }
1249
        // Return an empty list for file system items
649
            if (dataTransfer) {
1250
        // other than files or directories:
650
                dataTransfer.dropEffect = dataTransfer.effectAllowed = 'copy';
1251
        dfd.resolve([]);
-
 
1252
      }
651
            }
1253
      return dfd.promise();
-
 
1254
    },
652
            e.preventDefault();
1255
 
653
        },
1256
    _handleFileTreeEntries: function (entries, path) {
-
 
1257
      var that = this;
-
 
1258
      return $.when
654
        
1259
        .apply(
655
        _initEventHandlers: function () {
1260
          $,
656
            var ns = this.options.namespace || this.name;
1261
          $.map(entries, function (entry) {
-
 
1262
            return that._handleFileTreeEntry(entry, path);
657
            this.options.dropZone
1263
          })
-
 
1264
        )
-
 
1265
        [this._promisePipe](function () {
-
 
1266
          return Array.prototype.concat.apply([], arguments);
-
 
1267
        });
-
 
1268
    },
-
 
1269
 
-
 
1270
    _getDroppedFiles: function (dataTransfer) {
-
 
1271
      // eslint-disable-next-line no-param-reassign
-
 
1272
      dataTransfer = dataTransfer || {};
-
 
1273
      var items = dataTransfer.items;
658
                .bind('dragover.' + ns, {fileupload: this}, this._onDragOver)
1274
      if (
-
 
1275
        items &&
-
 
1276
        items.length &&
659
                .bind('drop.' + ns, {fileupload: this}, this._onDrop);
1277
        (items[0].webkitGetAsEntry || items[0].getAsEntry)
660
            this.options.fileInput
1278
      ) {
661
                .bind('change.' + ns, {fileupload: this}, this._onChange);
1279
        return this._handleFileTreeEntries(
662
        },
1280
          $.map(items, function (item) {
-
 
1281
            var entry;
663
 
1282
            if (item.webkitGetAsEntry) {
-
 
1283
              entry = item.webkitGetAsEntry();
664
        _destroyEventHandlers: function () {
1284
              if (entry) {
-
 
1285
                // Workaround for Chrome bug #149735:
665
            var ns = this.options.namespace || this.name;
1286
                entry._file = item.getAsFile();
-
 
1287
              }
-
 
1288
              return entry;
-
 
1289
            }
666
            this.options.dropZone
1290
            return item.getAsEntry();
667
                .unbind('dragover.' + ns, this._onDragOver)
1291
          })
-
 
1292
        );
-
 
1293
      }
668
                .unbind('drop.' + ns, this._onDrop);
1294
      return $.Deferred().resolve($.makeArray(dataTransfer.files)).promise();
669
            this.options.fileInput
1295
    },
-
 
1296
 
-
 
1297
    _getSingleFileInputFiles: function (fileInput) {
-
 
1298
      // eslint-disable-next-line no-param-reassign
670
                .unbind('change.' + ns, this._onChange);
1299
      fileInput = $(fileInput);
671
        },
1300
      var entries = fileInput.prop('entries'),
-
 
1301
        files,
672
        
1302
        value;
673
        _beforeSetOption: function (key, value) {
1303
      if (entries && entries.length) {
674
            this._destroyEventHandlers();
1304
        return this._handleFileTreeEntries(entries);
675
        },
1305
      }
-
 
1306
      files = $.makeArray(fileInput.prop('files'));
-
 
1307
      if (!files.length) {
-
 
1308
        value = fileInput.prop('value');
-
 
1309
        if (!value) {
-
 
1310
          return $.Deferred().resolve([]).promise();
-
 
1311
        }
676
        
1312
        // If the files property is not available, the browser does not
677
        _afterSetOption: function (key, value) {
1313
        // support the File API and we add a pseudo File object with
-
 
1314
        // the input value as name with path information removed:
678
            var options = this.options;
1315
        files = [{ name: value.replace(/^.*\\/, '') }];
-
 
1316
      } else if (files[0].name === undefined && files[0].fileName) {
-
 
1317
        // File normalization for Safari 4 and Firefox 3:
-
 
1318
        $.each(files, function (index, file) {
-
 
1319
          file.name = file.fileName;
-
 
1320
          file.size = file.fileSize;
-
 
1321
        });
-
 
1322
      }
-
 
1323
      return $.Deferred().resolve(files).promise();
-
 
1324
    },
-
 
1325
 
679
            if (!options.fileInput) {
1326
    _getFileInputFiles: function (fileInput) {
-
 
1327
      if (!(fileInput instanceof $) || fileInput.length === 1) {
680
                options.fileInput = $();
1328
        return this._getSingleFileInputFiles(fileInput);
-
 
1329
      }
681
            }
1330
      return $.when
682
            if (!options.dropZone) {
1331
        .apply($, $.map(fileInput, this._getSingleFileInputFiles))
-
 
1332
        [this._promisePipe](function () {
-
 
1333
          return Array.prototype.concat.apply([], arguments);
-
 
1334
        });
-
 
1335
    },
-
 
1336
 
683
                options.dropZone = $();
1337
    _onChange: function (e) {
684
            }
1338
      var that = this,
-
 
1339
        data = {
685
            this._initEventHandlers();
1340
          fileInput: $(e.target),
-
 
1341
          form: $(e.target.form)
686
        },
1342
        };
687
        
1343
      this._getFileInputFiles(data.fileInput).always(function (files) {
688
        _setOption: function (key, value) {
1344
        data.files = files;
689
            var refresh = $.inArray(key, this._refreshOptionsList) !== -1;
1345
        if (that.options.replaceFileInput) {
690
            if (refresh) {
1346
          that._replaceFileInput(data);
-
 
1347
        }
-
 
1348
        if (
-
 
1349
          that._trigger(
691
                this._beforeSetOption(key, value);
1350
            'change',
-
 
1351
            $.Event('change', { delegatedEvent: e }),
-
 
1352
            data
Zeile 692... Zeile 1353...
692
            }
1353
          ) !== false
-
 
1354
        ) {
693
            $.Widget.prototype._setOption.call(this, key, value);
1355
          that._onAdd(e, data);
694
            if (refresh) {
1356
        }
695
                this._afterSetOption(key, value);
1357
      });
-
 
1358
    },
696
            }
1359
 
697
        },
1360
    _onPaste: function (e) {
698
 
1361
      var items =
699
        _create: function () {
1362
          e.originalEvent &&
700
            var options = this.options;
1363
          e.originalEvent.clipboardData &&
-
 
1364
          e.originalEvent.clipboardData.items,
701
            if (options.fileInput === undefined) {
1365
        data = { files: [] };
702
                options.fileInput = this.element.is('input:file') ?
1366
      if (items && items.length) {
703
                    this.element : this.element.find('input:file');
1367
        $.each(items, function (index, item) {
704
            } else if (!options.fileInput) {
1368
          var file = item.getAsFile && item.getAsFile();
705
                options.fileInput = $();
1369
          if (file) {
706
            }
1370
            data.files.push(file);
707
            if (!options.dropZone) {
1371
          }
708
                options.dropZone = $();
-
 
709
            }
1372
        });
710
            this._slots = [];
1373
        if (
711
            this._sequence = this._getXHRPromise(true);
1374
          this._trigger(
712
            this._sending = this._active = this._loaded = this._total = 0;
1375
            'paste',
-
 
1376
            $.Event('paste', { delegatedEvent: e }),
Zeile 713... Zeile 1377...
713
            this._initEventHandlers();
1377
            data
-
 
1378
          ) !== false
-
 
1379
        ) {
-
 
1380
          this._onAdd(e, data);
-
 
1381
        }
-
 
1382
      }
-
 
1383
    },
-
 
1384
 
-
 
1385
    _onDrop: function (e) {
-
 
1386
      e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
-
 
1387
      var that = this,
-
 
1388
        dataTransfer = e.dataTransfer,
714
        },
1389
        data = {};
-
 
1390
      if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
-
 
1391
        e.preventDefault();
-
 
1392
        this._getDroppedFiles(dataTransfer).always(function (files) {
715
        
1393
          data.files = files;
-
 
1394
          if (
-
 
1395
            that._trigger(
-
 
1396
              'drop',
-
 
1397
              $.Event('drop', { delegatedEvent: e }),
-
 
1398
              data
-
 
1399
            ) !== false
-
 
1400
          ) {
-
 
1401
            that._onAdd(e, data);
-
 
1402
          }
-
 
1403
        });
-
 
1404
      }
-
 
1405
    },
-
 
1406
 
-
 
1407
    _onDragOver: getDragHandler('dragover'),
-
 
1408
 
-
 
1409
    _onDragEnter: getDragHandler('dragenter'),
-
 
1410
 
-
 
1411
    _onDragLeave: getDragHandler('dragleave'),
-
 
1412
 
-
 
1413
    _initEventHandlers: function () {
-
 
1414
      if (this._isXHRUpload(this.options)) {
-
 
1415
        this._on(this.options.dropZone, {
-
 
1416
          dragover: this._onDragOver,
-
 
1417
          drop: this._onDrop,
-
 
1418
          // event.preventDefault() on dragenter is required for IE10+:
-
 
1419
          dragenter: this._onDragEnter,
-
 
1420
          // dragleave is not required, but added for completeness:
-
 
1421
          dragleave: this._onDragLeave
716
        destroy: function () {
1422
        });
-
 
1423
        this._on(this.options.pasteZone, {
-
 
1424
          paste: this._onPaste
-
 
1425
        });
-
 
1426
      }
-
 
1427
      if ($.support.fileInput) {
-
 
1428
        this._on(this.options.fileInput, {
-
 
1429
          change: this._onChange
-
 
1430
        });
717
            this._destroyEventHandlers();
1431
      }
718
            $.Widget.prototype.destroy.call(this);
1432
    },
-
 
1433
 
-
 
1434
    _destroyEventHandlers: function () {
-
 
1435
      this._off(this.options.dropZone, 'dragenter dragleave dragover drop');
-
 
1436
      this._off(this.options.pasteZone, 'paste');
-
 
1437
      this._off(this.options.fileInput, 'change');
-
 
1438
    },
719
        },
1439
 
-
 
1440
    _destroy: function () {
-
 
1441
      this._destroyEventHandlers();
-
 
1442
    },
-
 
1443
 
-
 
1444
    _setOption: function (key, value) {
-
 
1445
      var reinit = $.inArray(key, this._specialOptions) !== -1;
-
 
1446
      if (reinit) {
-
 
1447
        this._destroyEventHandlers();
-
 
1448
      }
-
 
1449
      this._super(key, value);
-
 
1450
      if (reinit) {
-
 
1451
        this._initSpecialOptions();
-
 
1452
        this._initEventHandlers();
-
 
1453
      }
-
 
1454
    },
-
 
1455
 
-
 
1456
    _initSpecialOptions: function () {
-
 
1457
      var options = this.options;
-
 
1458
      if (options.fileInput === undefined) {
-
 
1459
        options.fileInput = this.element.is('input[type="file"]')
-
 
1460
          ? this.element
-
 
1461
          : this.element.find('input[type="file"]');
-
 
1462
      } else if (!(options.fileInput instanceof $)) {
-
 
1463
        options.fileInput = $(options.fileInput);
-
 
1464
      }
-
 
1465
      if (!(options.dropZone instanceof $)) {
-
 
1466
        options.dropZone = $(options.dropZone);
-
 
1467
      }
-
 
1468
      if (!(options.pasteZone instanceof $)) {
-
 
1469
        options.pasteZone = $(options.pasteZone);
-
 
1470
      }
-
 
1471
    },
-
 
1472
 
-
 
1473
    _getRegExp: function (str) {
-
 
1474
      var parts = str.split('/'),
-
 
1475
        modifiers = parts.pop();
-
 
1476
      parts.shift();
-
 
1477
      return new RegExp(parts.join('/'), modifiers);
-
 
1478
    },
-
 
1479
 
-
 
1480
    _isRegExpOption: function (key, value) {
-
 
1481
      return (
-
 
1482
        key !== 'url' &&
-
 
1483
        $.type(value) === 'string' &&
-
 
1484
        /^\/.*\/[igm]{0,3}$/.test(value)
-
 
1485
      );
-
 
1486
    },
-
 
1487
 
-
 
1488
    _initDataAttributes: function () {
-
 
1489
      var that = this,
-
 
1490
        options = this.options,
720
 
1491
        data = this.element.data();
-
 
1492
      // Initialize options set via HTML5 data-attributes:
-
 
1493
      $.each(this.element[0].attributes, function (index, attr) {
-
 
1494
        var key = attr.name.toLowerCase(),
-
 
1495
          value;
-
 
1496
        if (/^data-/.test(key)) {
-
 
1497
          // Convert hyphen-ated key to camelCase:
721
        enable: function () {
1498
          key = key.slice(5).replace(/-[a-z]/g, function (str) {
-
 
1499
            return str.charAt(1).toUpperCase();
-
 
1500
          });
Zeile -... Zeile 1501...
-
 
1501
          value = data[key];
-
 
1502
          if (that._isRegExpOption(key, value)) {
-
 
1503
            value = that._getRegExp(value);
-
 
1504
          }
-
 
1505
          options[key] = value;
-
 
1506
        }
-
 
1507
      });
-
 
1508
    },
-
 
1509
 
-
 
1510
    _create: function () {
-
 
1511
      this._initDataAttributes();
-
 
1512
      this._initSpecialOptions();
-
 
1513
      this._slots = [];
-
 
1514
      this._sequence = this._getXHRPromise(true);
-
 
1515
      this._sending = this._active = 0;
-
 
1516
      this._initProgressObject(this);
-
 
1517
      this._initEventHandlers();
-
 
1518
    },
-
 
1519
 
-
 
1520
    // This method is exposed to the widget API and allows to query
-
 
1521
    // the number of active uploads:
-
 
1522
    active: function () {
-
 
1523
      return this._active;
-
 
1524
    },
722
            $.Widget.prototype.enable.call(this);
1525
 
723
            this._initEventHandlers();
1526
    // This method is exposed to the widget API and allows to query
724
        },
1527
    // the widget upload progress.
725
        
1528
    // It returns an object with loaded, total and bitrate properties
726
        disable: function () {
1529
    // for the running uploads:
-
 
1530
    progress: function () {
727
            this._destroyEventHandlers();
1531
      return this._progress;
-
 
1532
    },
-
 
1533
 
-
 
1534
    // This method is exposed to the widget API and allows adding files
-
 
1535
    // using the fileupload API. The data parameter accepts an object which
-
 
1536
    // must have a files property and can contain additional options:
-
 
1537
    // .fileupload('add', {files: filesList});
-
 
1538
    add: function (data) {
-
 
1539
      var that = this;
-
 
1540
      if (!data || this.options.disabled) {
-
 
1541
        return;
-
 
1542
      }
-
 
1543
      if (data.fileInput && !data.files) {
-
 
1544
        this._getFileInputFiles(data.fileInput).always(function (files) {
-
 
1545
          data.files = files;
-
 
1546
          that._onAdd(null, data);
-
 
1547
        });
-
 
1548
      } else {
-
 
1549
        data.files = $.makeArray(data.files);
-
 
1550
        this._onAdd(null, data);
-
 
1551
      }
-
 
1552
    },
-
 
1553
 
-
 
1554
    // This method is exposed to the widget API and allows sending files
-
 
1555
    // using the fileupload API. The data parameter accepts an object which
-
 
1556
    // must have a files or fileInput property and can contain additional options:
728
            $.Widget.prototype.disable.call(this);
1557
    // .fileupload('send', {files: filesList});
-
 
1558
    // The method returns a Promise object for the file upload call.
-
 
1559
    send: function (data) {
-
 
1560
      if (data && !this.options.disabled) {
-
 
1561
        if (data.fileInput && !data.files) {
729
        },
1562
          var that = this,
730
 
1563
            dfd = $.Deferred(),
731
        // This method is exposed to the widget API and allows adding files
1564
            promise = dfd.promise(),
732
        // using the fileupload API. The data parameter accepts an object which
1565
            jqXHR,
733
        // must have a files property and can contain additional options:
-
 
734
        // .fileupload('add', {files: filesList});
1566
            aborted;
735
        add: function (data) {
1567
          promise.abort = function () {
-
 
1568
            aborted = true;
-
 
1569
            if (jqXHR) {
736
            if (!data || this.options.disabled) {
1570
              return jqXHR.abort();
-
 
1571
            }
-
 
1572
            dfd.reject(null, 'abort', 'abort');
-
 
1573
            return promise;
737
                return;
1574
          };
738
            }
1575
          this._getFileInputFiles(data.fileInput).always(function (files) {
739
            data.files = $.each($.makeArray(data.files), this._normalizeFile);
1576
            if (aborted) {
740
            this._onAdd(null, data);
1577
              return;
741
        },
1578
            }
-
 
1579
            if (!files.length) {
742
        
1580
              dfd.reject();
743
        // This method is exposed to the widget API and allows sending files
1581
              return;
744
        // using the fileupload API. The data parameter accepts an object which
1582
            }
745
        // must have a files property and can contain additional options:
1583
            data.files = files;
-
 
1584
            jqXHR = that._onSend(null, data);
746
        // .fileupload('send', {files: filesList});
1585
            jqXHR.then(
-
 
1586
              function (result, textStatus, jqXHR) {
-
 
1587
                dfd.resolve(result, textStatus, jqXHR);
-
 
1588
              },
-
 
1589
              function (jqXHR, textStatus, errorThrown) {
747
        // The method returns a Promise object for the file upload call.
1590
                dfd.reject(jqXHR, textStatus, errorThrown);
748
        send: function (data) {
-
 
749
            if (data && !this.options.disabled) {
-
 
750
                data.files = $.each($.makeArray(data.files), this._normalizeFile);
-
 
751
                if (data.files.length) {
-
 
752
                    return this._onSend(null, data);
1591
              }
-
 
1592
            );
-
 
1593
          });
-
 
1594
          return this._enhancePromise(promise);
-
 
1595
        }
-
 
1596
        data.files = $.makeArray(data.files);