|
1 | 1 | /*
|
2 |
| - * jQuery File Upload Plugin 5.8.1 |
| 2 | + * jQuery File Upload Plugin 5.10.0 |
3 | 3 | * https://github.com/blueimp/jQuery-File-Upload
|
4 | 4 | *
|
5 | 5 | * Copyright 2010, Sebastian Tschan
|
|
10 | 10 | */
|
11 | 11 |
|
12 | 12 | /*jslint nomen: true, unparam: true, regexp: true */
|
13 |
| -/*global define, window, document, XMLHttpRequestUpload, Blob, File, FormData, location */ |
| 13 | +/*global define, window, document, Blob, FormData, location */ |
14 | 14 |
|
15 | 15 | (function (factory) {
|
16 | 16 | 'use strict';
|
|
27 | 27 | }(function ($) {
|
28 | 28 | 'use strict';
|
29 | 29 |
|
| 30 | + // The FileReader API is not actually used, but works as feature detection, |
| 31 | + // as e.g. Safari supports XHR file uploads via the FormData API, |
| 32 | + // but not non-multipart XHR file uploads: |
| 33 | + $.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader); |
| 34 | + $.support.xhrFormDataFileUpload = !!window.FormData; |
| 35 | + |
30 | 36 | // The fileupload widget listens for change events on file input fields defined
|
31 | 37 | // via fileInput setting and paste or drop events of the given dropZone.
|
32 | 38 | // In addition to the default jQuery Widget methods, the fileupload widget
|
|
57 | 63 | replaceFileInput: true,
|
58 | 64 | // The parameter name for the file form data (the request argument name).
|
59 | 65 | // If undefined or empty, the name property of the file input field is
|
60 |
| - // used, or "files[]" if the file input name property is also empty: |
| 66 | + // used, or "files[]" if the file input name property is also empty, |
| 67 | + // can be a string or an array of strings: |
61 | 68 | paramName: undefined,
|
62 | 69 | // By default, each file of a selection is uploaded using an individual
|
63 | 70 | // request for XHR type uploads. Set to false to upload file
|
|
165 | 172 | },
|
166 | 173 |
|
167 | 174 | // A list of options that require a refresh after assigning a new value:
|
168 |
| - _refreshOptionsList: ['namespace', 'dropZone', 'fileInput'], |
| 175 | + _refreshOptionsList: [ |
| 176 | + 'namespace', |
| 177 | + 'dropZone', |
| 178 | + 'fileInput', |
| 179 | + 'multipart', |
| 180 | + 'forceIframeTransport' |
| 181 | + ], |
169 | 182 |
|
170 | 183 | _isXHRUpload: function (options) {
|
171 |
| - var undef = 'undefined'; |
172 | 184 | return !options.forceIframeTransport &&
|
173 |
| - typeof XMLHttpRequestUpload !== undef && typeof File !== undef && |
174 |
| - (!options.multipart || typeof FormData !== undef); |
| 185 | + ((!options.multipart && $.support.xhrFileUpload) || |
| 186 | + $.support.xhrFormDataFileUpload); |
175 | 187 | },
|
176 | 188 |
|
177 | 189 | _getFormData: function (options) {
|
|
245 | 257 |
|
246 | 258 | _initXHRData: function (options) {
|
247 | 259 | var formData,
|
248 |
| - file = options.files[0]; |
249 |
| - if (!options.multipart || options.blob) { |
| 260 | + file = options.files[0], |
| 261 | + // Ignore non-multipart setting if not supported: |
| 262 | + multipart = options.multipart || !$.support.xhrFileUpload, |
| 263 | + paramName = options.paramName[0]; |
| 264 | + if (!multipart || options.blob) { |
250 | 265 | // For non-multipart uploads and chunked uploads,
|
251 | 266 | // file meta data is not part of the request body,
|
252 | 267 | // so we transmit this data as part of the HTTP headers.
|
|
262 | 277 | // Non-chunked non-multipart upload:
|
263 | 278 | options.contentType = file.type;
|
264 | 279 | options.data = file;
|
265 |
| - } else if (!options.multipart) { |
| 280 | + } else if (!multipart) { |
266 | 281 | // Chunked non-multipart upload:
|
267 | 282 | options.contentType = 'application/octet-stream';
|
268 | 283 | options.data = options.blob;
|
269 | 284 | }
|
270 | 285 | }
|
271 |
| - if (options.multipart && typeof FormData !== 'undefined') { |
| 286 | + if (multipart && $.support.xhrFormDataFileUpload) { |
272 | 287 | if (options.postMessage) {
|
273 | 288 | // window.postMessage does not allow sending FormData
|
274 | 289 | // objects, so we just add the File/Blob objects to
|
|
277 | 292 | formData = this._getFormData(options);
|
278 | 293 | if (options.blob) {
|
279 | 294 | formData.push({
|
280 |
| - name: options.paramName, |
| 295 | + name: paramName, |
281 | 296 | value: options.blob
|
282 | 297 | });
|
283 | 298 | } else {
|
284 | 299 | $.each(options.files, function (index, file) {
|
285 | 300 | formData.push({
|
286 |
| - name: options.paramName, |
| 301 | + name: options.paramName[index] || paramName, |
287 | 302 | value: file
|
288 | 303 | });
|
289 | 304 | });
|
|
298 | 313 | });
|
299 | 314 | }
|
300 | 315 | if (options.blob) {
|
301 |
| - formData.append(options.paramName, options.blob, file.name); |
| 316 | + formData.append(paramName, options.blob, file.name); |
302 | 317 | } else {
|
303 | 318 | $.each(options.files, function (index, file) {
|
304 | 319 | // File objects are also Blob instances.
|
305 | 320 | // This check allows the tests to run with
|
306 | 321 | // dummy objects:
|
307 | 322 | if (file instanceof Blob) {
|
308 |
| - formData.append(options.paramName, file, file.name); |
| 323 | + formData.append( |
| 324 | + options.paramName[index] || paramName, |
| 325 | + file, |
| 326 | + file.name |
| 327 | + ); |
309 | 328 | }
|
310 | 329 | });
|
311 | 330 | }
|
|
349 | 368 | }
|
350 | 369 | },
|
351 | 370 |
|
| 371 | + _getParamName: function (options) { |
| 372 | + var fileInput = $(options.fileInput), |
| 373 | + paramName = options.paramName; |
| 374 | + if (!paramName) { |
| 375 | + paramName = []; |
| 376 | + fileInput.each(function () { |
| 377 | + var input = $(this), |
| 378 | + name = input.prop('name') || 'files[]', |
| 379 | + i = (input.prop('files') || [1]).length; |
| 380 | + while (i) { |
| 381 | + paramName.push(name); |
| 382 | + i -= 1; |
| 383 | + } |
| 384 | + }); |
| 385 | + if (!paramName.length) { |
| 386 | + paramName = [fileInput.prop('name') || 'files[]']; |
| 387 | + } |
| 388 | + } else if (!$.isArray(paramName)) { |
| 389 | + paramName = [paramName]; |
| 390 | + } |
| 391 | + return paramName; |
| 392 | + }, |
| 393 | + |
352 | 394 | _initFormSettings: function (options) {
|
353 | 395 | // Retrieve missing options from the input field and the
|
354 | 396 | // associated form, if available:
|
355 | 397 | if (!options.form || !options.form.length) {
|
356 | 398 | options.form = $(options.fileInput.prop('form'));
|
357 | 399 | }
|
358 |
| - if (!options.paramName) { |
359 |
| - options.paramName = options.fileInput.prop('name') || |
360 |
| - 'files[]'; |
361 |
| - } |
| 400 | + options.paramName = this._getParamName(options); |
362 | 401 | if (!options.url) {
|
363 | 402 | options.url = options.form.prop('action') || location.href;
|
364 | 403 | }
|
|
621 | 660 | result = true,
|
622 | 661 | options = $.extend({}, this.options, data),
|
623 | 662 | limit = options.limitMultiFileUploads,
|
| 663 | + paramName = this._getParamName(options), |
| 664 | + paramNameSet, |
| 665 | + paramNameSlice, |
624 | 666 | fileSet,
|
625 | 667 | i;
|
626 | 668 | if (!(options.singleFileUploads || limit) ||
|
627 | 669 | !this._isXHRUpload(options)) {
|
628 | 670 | fileSet = [data.files];
|
| 671 | + paramNameSet = [paramName]; |
629 | 672 | } else if (!options.singleFileUploads && limit) {
|
630 | 673 | fileSet = [];
|
| 674 | + paramNameSet = []; |
631 | 675 | for (i = 0; i < data.files.length; i += limit) {
|
632 | 676 | fileSet.push(data.files.slice(i, i + limit));
|
| 677 | + paramNameSlice = paramName.slice(i, i + limit); |
| 678 | + if (!paramNameSlice.length) { |
| 679 | + paramNameSlice = paramName; |
| 680 | + } |
| 681 | + paramNameSet.push(paramNameSlice); |
633 | 682 | }
|
| 683 | + } else { |
| 684 | + paramNameSet = paramName; |
634 | 685 | }
|
635 | 686 | data.originalFiles = data.files;
|
636 | 687 | $.each(fileSet || data.files, function (index, element) {
|
637 |
| - var files = fileSet ? element : [element], |
638 |
| - newData = $.extend({}, data, {files: files}); |
| 688 | + var newData = $.extend({}, data); |
| 689 | + newData.files = fileSet ? element : [element]; |
| 690 | + newData.paramName = paramNameSet[index]; |
639 | 691 | newData.submit = function () {
|
640 | 692 | newData.jqXHR = this.jqXHR =
|
641 | 693 | (that._trigger('submit', e, this) !== false) &&
|
|
748 | 800 |
|
749 | 801 | _initEventHandlers: function () {
|
750 | 802 | var ns = this.options.namespace;
|
751 |
| - this.options.dropZone |
752 |
| - .bind('dragover.' + ns, {fileupload: this}, this._onDragOver) |
753 |
| - .bind('drop.' + ns, {fileupload: this}, this._onDrop) |
754 |
| - .bind('paste.' + ns, {fileupload: this}, this._onPaste); |
| 803 | + if (this._isXHRUpload(this.options)) { |
| 804 | + this.options.dropZone |
| 805 | + .bind('dragover.' + ns, {fileupload: this}, this._onDragOver) |
| 806 | + .bind('drop.' + ns, {fileupload: this}, this._onDrop) |
| 807 | + .bind('paste.' + ns, {fileupload: this}, this._onPaste); |
| 808 | + } |
755 | 809 | this.options.fileInput
|
756 | 810 | .bind('change.' + ns, {fileupload: this}, this._onChange);
|
757 | 811 | },
|
|
0 commit comments