From 27f55b01d7c14194092c2216de35fb3bc3ef950f Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Thu, 31 Jul 2014 17:42:01 -0700 Subject: [PATCH] Updating jQuery Upload plugin --- .../Orchard.jQuery/ResourceManifest.cs | 4 +- .../Scripts/jquery.fileupload.js | 420 +++++++++++++----- .../Scripts/jquery.fileupload.min.js | 3 +- .../Scripts/jquery.iframe-transport.js | 61 ++- .../Scripts/jquery.iframe-transport.min.js | 3 +- 5 files changed, 363 insertions(+), 128 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.jQuery/ResourceManifest.cs b/src/Orchard.Web/Modules/Orchard.jQuery/ResourceManifest.cs index 3b5289c92..ad173b16f 100644 --- a/src/Orchard.Web/Modules/Orchard.jQuery/ResourceManifest.cs +++ b/src/Orchard.Web/Modules/Orchard.jQuery/ResourceManifest.cs @@ -80,8 +80,8 @@ namespace Orchard.jQuery { manifest.DefineStyle("jQueryDateTimeEditor").SetUrl("jquery-datetime-editor.css").SetDependencies("DateTimeEditor"); // jQuery File Upload - manifest.DefineScript("jQueryIFrameTransport").SetUrl("jquery.iframe-transport.min.js", "jquery.iframe-transport.js").SetVersion("1.6.1").SetDependencies("jQuery"); - manifest.DefineScript("jQueryFileUpload").SetUrl("jquery.fileupload.min.js", "jquery.fileupload.js").SetVersion("1.6.1").SetDependencies("jQueryIFrameTransport").SetDependencies("jQueryUI_Widget"); + manifest.DefineScript("jQueryIFrameTransport").SetUrl("jquery.iframe-transport.min.js", "jquery.iframe-transport.js").SetVersion("1.8.2").SetDependencies("jQuery"); + manifest.DefineScript("jQueryFileUpload").SetUrl("jquery.fileupload.min.js", "jquery.fileupload.js").SetVersion("5.41.0").SetDependencies("jQueryIFrameTransport").SetDependencies("jQueryUI_Widget"); // jquer Color Box manifest.DefineScript("jQueryColorBox").SetUrl("jquery.colorbox.min.js", "jquery.colorbox.js").SetVersion("1.4.10").SetDependencies("jQuery"); diff --git a/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.fileupload.js b/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.fileupload.js index 78bffafec..5461765e1 100644 --- a/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.fileupload.js +++ b/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.fileupload.js @@ -1,5 +1,5 @@ /* - * jQuery File Upload Plugin 5.28.5 + * jQuery File Upload Plugin 5.41.0 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2010, Sebastian Tschan @@ -9,8 +9,8 @@ * http://www.opensource.org/licenses/MIT */ -/*jslint nomen: true, unparam: true, regexp: true */ -/*global define, window, document, File, Blob, FormData, location */ +/* jshint nomen:false */ +/* global define, window, document, location, Blob, FormData */ (function (factory) { 'use strict'; @@ -27,12 +27,30 @@ }(function ($) { 'use strict'; + // Detect file input support, based on + // http://viljamis.com/blog/2012/file-upload-support-on-mobile/ + $.support.fileInput = !(new RegExp( + // Handle devices which give false positives for the feature detection: + '(Android (1\\.[0156]|2\\.[01]))' + + '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' + + '|(w(eb)?OSBrowser)|(webOS)' + + '|(Kindle/(1\\.0|2\\.[05]|3\\.0))' + ).test(window.navigator.userAgent) || + // Feature detection for all other devices: + $('').prop('disabled')); + // The FileReader API is not actually used, but works as feature detection, - // as e.g. Safari supports XHR file uploads via the FormData API, - // but not non-multipart XHR file uploads: - $.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader); + // as some Safari versions (5?) support XHR file uploads via the FormData API, + // but not non-multipart XHR file uploads. + // window.XMLHttpRequestUpload is not available on IE10, so we check for + // window.ProgressEvent instead to detect XHR2 file upload capability: + $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader); $.support.xhrFormDataFileUpload = !!window.FormData; + // Detect support for Blob slicing (required for chunked uploads): + $.support.blobSlice = window.Blob && (Blob.prototype.slice || + Blob.prototype.webkitSlice || Blob.prototype.mozSlice); + // The fileupload widget listens for change events on file input fields defined // via fileInput setting and paste or drop events of the given dropZone. // In addition to the default jQuery Widget methods, the fileupload widget @@ -72,6 +90,14 @@ // To limit the number of files uploaded with one XHR request, // set the following option to an integer greater than 0: limitMultiFileUploads: undefined, + // The following option limits the number of files uploaded with one + // XHR request to keep the request size under or equal to the defined + // limit in bytes: + limitMultiFileUploadSize: undefined, + // Multipart file uploads add a number of bytes to each uploaded file, + // therefore the following option adds an overhead for each file used + // in the limitMultiFileUploadSize configuration: + limitMultiFileUploadSizeOverhead: 512, // Set the following option to true to issue all file upload requests // in a sequential order: sequentialUploads: false, @@ -115,6 +141,23 @@ // By default, uploads are started automatically when adding files: autoUpload: true, + // Error and info messages: + messages: { + uploadedBytes: 'Uploaded bytes exceed file size' + }, + + // Translation function, gets the message key to be translated + // and an object with context specific data as arguments: + i18n: function (message, context) { + message = this.messages[message] || message.toString(); + if (context) { + $.each(context, function (key, value) { + message = message.replace('{' + key + '}', value); + }); + } + return message; + }, + // Additional form data to be sent along with the file uploads can be set // using this option, which accepts an array of objects with name and // value properties, a function returning such an array, a FormData @@ -127,21 +170,28 @@ // The add callback is invoked as soon as files are added to the fileupload // widget (via file input selection, drag & drop, paste or add API call). // If the singleFileUploads option is enabled, this callback will be - // called once for each file in the selection for XHR file uplaods, else + // called once for each file in the selection for XHR file uploads, else // once for each file selection. + // // The upload starts when the submit method is invoked on the data parameter. // The data object contains a files property holding the added files - // and allows to override plugin options as well as define ajax settings. + // and allows you to override plugin options as well as define ajax settings. + // // Listeners for this callback can also be bound the following way: // .bind('fileuploadadd', func); + // // data.submit() returns a Promise object and allows to attach additional // handlers using jQuery's Deferred callbacks: // data.submit().done(func).fail(func).always(func); add: function (e, data) { + if (e.isDefaultPrevented()) { + return false; + } if (data.autoUpload || (data.autoUpload !== false && - ($(this).data('blueimp-fileupload') || - $(this).data('fileupload')).options.autoUpload)) { - data.submit(); + $(this).fileupload('option', 'autoUpload'))) { + data.process().done(function () { + data.submit(); + }); } }, @@ -205,8 +255,9 @@ cache: false }, - // A list of options that require a refresh after assigning a new value: - _refreshOptionsList: [ + // A list of options that require reinitializing event listeners and/or + // special initialization code: + _specialOptions: [ 'fileInput', 'dropZone', 'pasteZone', @@ -214,6 +265,11 @@ 'forceIframeTransport' ], + _blobSlice: $.support.blobSlice && function () { + var slice = this.slice || this.webkitSlice || this.mozSlice; + return slice.apply(this, arguments); + }, + _BitrateTimer: function () { this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime()); this.loaded = 0; @@ -237,7 +293,7 @@ _getFormData: function (options) { var formData; - if (typeof options.formData === 'function') { + if ($.type(options.formData) === 'function') { return options.formData(options.form); } if ($.isArray(options.formData)) { @@ -246,7 +302,7 @@ if ($.type(options.formData) === 'object') { formData = []; $.each(options.formData, function (name, value) { - formData.push({name: name, value: value}); + formData.push({ name: name, value: value }); }); return formData; } @@ -317,10 +373,18 @@ // Trigger a custom progress event with a total data property set // to the file size(s) of the current upload and a loaded data // property calculated accordingly: - this._trigger('progress', e, data); + this._trigger( + 'progress', + $.Event('progress', { delegatedEvent: e }), + data + ); // Trigger a global progress event for all current file uploads, // including ajax calls queued for sequential file uploads: - this._trigger('progressall', e, this._progress); + this._trigger( + 'progressall', + $.Event('progressall', { delegatedEvent: e }), + this._progress + ); } }, @@ -344,20 +408,29 @@ } }, + _isInstanceOf: function (type, obj) { + // Cross-frame instanceof check + return Object.prototype.toString.call(obj) === '[object ' + type + ']'; + }, + _initXHRData: function (options) { - var formData, + var that = this, + formData, file = options.files[0], // Ignore non-multipart setting if not supported: multipart = options.multipart || !$.support.xhrFileUpload, - paramName = options.paramName[0]; - options.headers = options.headers || {}; + paramName = $.type(options.paramName) === 'array' ? + options.paramName[0] : options.paramName; + options.headers = $.extend({}, options.headers); if (options.contentRange) { options.headers['Content-Range'] = options.contentRange; } - if (!multipart) { + if (!multipart || options.blob || !this._isInstanceOf('File', file)) { options.headers['Content-Disposition'] = 'attachment; filename="' + encodeURI(file.name) + '"'; - options.contentType = file.type; + } + if (!multipart) { + options.contentType = file.type || 'application/octet-stream'; options.data = options.blob || file; } else if ($.support.xhrFormDataFileUpload) { if (options.postMessage) { @@ -374,13 +447,14 @@ } else { $.each(options.files, function (index, file) { formData.push({ - name: options.paramName[index] || paramName, + name: ($.type(options.paramName) === 'array' && + options.paramName[index]) || paramName, value: file }); }); } } else { - if (options.formData instanceof FormData) { + if (that._isInstanceOf('FormData', options.formData)) { formData = options.formData; } else { formData = new FormData(); @@ -389,21 +463,18 @@ }); } if (options.blob) { - options.headers['Content-Disposition'] = 'attachment; filename="' + - encodeURI(file.name) + '"'; formData.append(paramName, options.blob, file.name); } else { $.each(options.files, function (index, file) { - // Files are also Blob instances, but some browsers - // (Firefox 3.6) support the File API but not Blobs. // This check allows the tests to run with // dummy objects: - if ((window.Blob && Object.prototype.toString.call(file) === '[object Blob]') || - (window.File && Object.prototype.toString.call(file) === '[object File]')) { + if (that._isInstanceOf('File', file) || + that._isInstanceOf('Blob', file)) { formData.append( - options.paramName[index] || paramName, + ($.type(options.paramName) === 'array' && + options.paramName[index]) || paramName, file, - file.name + file.uploadName || file.name ); } }); @@ -416,13 +487,13 @@ }, _initIframeSettings: function (options) { + var targetHost = $('').prop('href', options.url).prop('host'); // Setting the dataType to iframe enables the iframe transport: options.dataType = 'iframe ' + (options.dataType || ''); // The iframe transport accepts a serialized array as form data: options.formData = this._getFormData(options); // Add redirect url to form data on cross-domain uploads: - if (options.redirect && $('').prop('href', options.url) - .prop('host') !== location.host) { + if (options.redirect && targetHost && targetHost !== location.host) { options.formData.push({ name: options.redirectParamName || 'redirect', value: options.redirect @@ -444,7 +515,7 @@ options.dataType = 'postmessage ' + (options.dataType || ''); } } else { - this._initIframeSettings(options, 'iframe'); + this._initIframeSettings(options); } }, @@ -487,8 +558,10 @@ options.url = options.form.prop('action') || location.href; } // The HTTP request method must be "POST" or "PUT": - options.type = (options.type || options.form.prop('method') || '') - .toUpperCase(); + options.type = (options.type || + ($.type(options.form.prop('method')) === 'string' && + options.form.prop('method')) || '' + ).toUpperCase(); if (options.type !== 'POST' && options.type !== 'PUT' && options.type !== 'PATCH') { options.type = 'POST'; @@ -544,14 +617,35 @@ return this._enhancePromise(promise); }, - // Adds convenience methods to the callback arguments: + // Adds convenience methods to the data callback argument: _addConvenienceMethods: function (e, data) { - var that = this; + var that = this, + getPromise = function (args) { + return $.Deferred().resolveWith(that, args).promise(); + }; + data.process = function (resolveFunc, rejectFunc) { + if (resolveFunc || rejectFunc) { + data._processQueue = this._processQueue = + (this._processQueue || getPromise([this])).pipe( + function () { + if (data.errorThrown) { + return $.Deferred() + .rejectWith(that, [data]).promise(); + } + return getPromise(arguments); + } + ).pipe(resolveFunc, rejectFunc); + } + return this._processQueue || getPromise([this]); + }; data.submit = function () { if (this.state() !== 'pending') { data.jqXHR = this.jqXHR = - (that._trigger('submit', e, this) !== false) && - that._onSend(e, this); + (that._trigger( + 'submit', + $.Event('submit', { delegatedEvent: e }), + this + ) !== false) && that._onSend(e, this); } return this.jqXHR || that._getXHRPromise(); }; @@ -559,12 +653,21 @@ if (this.jqXHR) { return this.jqXHR.abort(); } - return that._getXHRPromise(); + this.errorThrown = 'abort'; + that._trigger('fail', null, this); + return that._getXHRPromise(false); }; data.state = function () { if (this.jqXHR) { return that._getDeferredState(this.jqXHR); } + if (this._processQueue) { + return that._getDeferredState(this._processQueue); + } + }; + data.processing = function () { + return !this.jqXHR && this._processQueue && that + ._getDeferredState(this._processQueue) === 'pending'; }; data.progress = function () { return this._progress; @@ -590,12 +693,13 @@ // should be uploaded in chunks, but does not invoke any // upload requests: _chunkedUpload: function (options, testOnly) { + options.uploadedBytes = options.uploadedBytes || 0; var that = this, file = options.files[0], fs = file.size, - ub = options.uploadedBytes = options.uploadedBytes || 0, + ub = options.uploadedBytes, mcs = options.maxChunkSize || fs, - slice = file.slice || file.webkitSlice || file.mozSlice, + slice = this._blobSlice, dfd = $.Deferred(), promise = dfd.promise(), jqXHR, @@ -608,7 +712,7 @@ return true; } if (ub >= fs) { - file.error = 'Uploaded bytes exceed file size'; + file.error = options.i18n('uploadedBytes'); return this._getXHRPromise( false, options.context, @@ -644,7 +748,7 @@ // Create a progress event if no final progress event // with loaded equaling total has been triggered // for this chunk: - if (o._progress.loaded === currentLoaded) { + if (currentLoaded + o.chunkSize - o._progress.loaded) { that._onProgress($.Event('progress', { lengthComputable: true, loaded: ub - o.uploadedBytes, @@ -767,7 +871,11 @@ // Set timer for bitrate progress calculation: options._bitrateTimer = new that._BitrateTimer(); jqXHR = jqXHR || ( - ((aborted || that._trigger('send', e, options) === false) && + ((aborted || that._trigger( + 'send', + $.Event('send', { delegatedEvent: e }), + options + ) === false) && that._getXHRPromise(false, options.context, aborted)) || that._chunkedUpload(options) || $.ajax(options) ).done(function (result, textStatus, jqXHR) { @@ -813,7 +921,8 @@ this._slots.push(slot); pipe = slot.pipe(send); } else { - pipe = (this._sequence = this._sequence.pipe(send, send)); + this._sequence = this._sequence.pipe(send, send); + pipe = this._sequence; } // Return the piped Promise object, enhanced with an abort method, // which is delegated to the jqXHR object of the current upload, @@ -837,46 +946,80 @@ var that = this, result = true, options = $.extend({}, this.options, data), + files = data.files, + filesLength = files.length, limit = options.limitMultiFileUploads, + limitSize = options.limitMultiFileUploadSize, + overhead = options.limitMultiFileUploadSizeOverhead, + batchSize = 0, paramName = this._getParamName(options), paramNameSet, paramNameSlice, fileSet, - i; - if (!(options.singleFileUploads || limit) || + i, + j = 0; + if (limitSize && (!filesLength || files[0].size === undefined)) { + limitSize = undefined; + } + if (!(options.singleFileUploads || limit || limitSize) || !this._isXHRUpload(options)) { - fileSet = [data.files]; + fileSet = [files]; paramNameSet = [paramName]; - } else if (!options.singleFileUploads && limit) { + } else if (!(options.singleFileUploads || limitSize) && limit) { fileSet = []; paramNameSet = []; - for (i = 0; i < data.files.length; i += limit) { - fileSet.push(data.files.slice(i, i + limit)); + for (i = 0; i < filesLength; i += limit) { + fileSet.push(files.slice(i, i + limit)); paramNameSlice = paramName.slice(i, i + limit); if (!paramNameSlice.length) { paramNameSlice = paramName; } paramNameSet.push(paramNameSlice); } + } else if (!options.singleFileUploads && limitSize) { + fileSet = []; + paramNameSet = []; + for (i = 0; i < filesLength; i = i + 1) { + batchSize += files[i].size + overhead; + if (i + 1 === filesLength || + ((batchSize + files[i + 1].size + overhead) > limitSize) || + (limit && i + 1 - j >= limit)) { + fileSet.push(files.slice(j, i + 1)); + paramNameSlice = paramName.slice(j, i + 1); + if (!paramNameSlice.length) { + paramNameSlice = paramName; + } + paramNameSet.push(paramNameSlice); + j = i + 1; + batchSize = 0; + } + } } else { paramNameSet = paramName; } - data.originalFiles = data.files; - $.each(fileSet || data.files, function (index, element) { + data.originalFiles = files; + $.each(fileSet || files, function (index, element) { var newData = $.extend({}, data); newData.files = fileSet ? element : [element]; newData.paramName = paramNameSet[index]; that._initResponseObject(newData); that._initProgressObject(newData); that._addConvenienceMethods(e, newData); - result = that._trigger('add', e, newData); + result = that._trigger( + 'add', + $.Event('add', { delegatedEvent: e }), + newData + ); return result; }); return result; }, - _replaceFileInput: function (input) { - var inputClone = input.clone(true); + _replaceFileInput: function (data) { + var input = data.fileInput, + inputClone = input.clone(true); + // Add a reference for the new cloned file input to the data argument: + data.fileInputClone = inputClone; $('
').append(inputClone)[0].reset(); // Detaching allows to insert the fileInput on another form // without loosing the file input value: @@ -912,7 +1055,25 @@ // to be returned together in one set: dfd.resolve([e]); }, - dirReader; + successHandler = function (entries) { + that._handleFileTreeEntries( + entries, + path + entry.name + '/' + ).done(function (files) { + dfd.resolve(files); + }).fail(errorHandler); + }, + readEntries = function () { + dirReader.readEntries(function (results) { + if (!results.length) { + successHandler(entries); + } else { + entries = entries.concat(results); + readEntries(); + } + }, errorHandler); + }, + dirReader, entries = []; path = path || ''; if (entry.isFile) { if (entry._file) { @@ -927,14 +1088,7 @@ } } else if (entry.isDirectory) { dirReader = entry.createReader(); - dirReader.readEntries(function (entries) { - that._handleFileTreeEntries( - entries, - path + entry.name + '/' - ).done(function (files) { - dfd.resolve(files); - }).fail(errorHandler); - }, errorHandler); + readEntries(); } else { // Return an empy list for file system items // other than files or directories: @@ -1001,7 +1155,7 @@ // If the files property is not available, the browser does not // support the File API and we add a pseudo File object with // the input value as name with path information removed: - files = [{name: value.replace(/^.*\\/, '')}]; + files = [{ name: value.replace(/^.*\\/, '') }]; } else if (files[0].name === undefined && files[0].fileName) { // File normalization for Safari 4 and Firefox 3: $.each(files, function (index, file) { @@ -1036,53 +1190,69 @@ this._getFileInputFiles(data.fileInput).always(function (files) { data.files = files; if (that.options.replaceFileInput) { - that._replaceFileInput(data.fileInput); + that._replaceFileInput(data); } - if (that._trigger('change', e, data) !== false) { + if (that._trigger( + 'change', + $.Event('change', { delegatedEvent: e }), + data + ) !== false) { that._onAdd(e, data); } }); }, _onPaste: function (e) { - var cbd = e.originalEvent.clipboardData, - items = (cbd && cbd.items) || [], - data = {files: []}; - $.each(items, function (index, item) { - var file = item.getAsFile && item.getAsFile(); - if (file) { - data.files.push(file); + var items = e.originalEvent && e.originalEvent.clipboardData && + e.originalEvent.clipboardData.items, + data = { files: [] }; + if (items && items.length) { + $.each(items, function (index, item) { + var file = item.getAsFile && item.getAsFile(); + if (file) { + data.files.push(file); + } + }); + if (this._trigger( + 'paste', + $.Event('paste', { delegatedEvent: e }), + data + ) !== false) { + this._onAdd(e, data); } - }); - if (this._trigger('paste', e, data) === false || - this._onAdd(e, data) === false) { - return false; } }, _onDrop: function (e) { + e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer; var that = this, - dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer, + dataTransfer = e.dataTransfer, data = {}; if (dataTransfer && dataTransfer.files && dataTransfer.files.length) { e.preventDefault(); + this._getDroppedFiles(dataTransfer).always(function (files) { + data.files = files; + if (that._trigger( + 'drop', + $.Event('drop', { delegatedEvent: e }), + data + ) !== false) { + that._onAdd(e, data); + } + }); } - this._getDroppedFiles(dataTransfer).always(function (files) { - data.files = files; - if (that._trigger('drop', e, data) !== false) { - that._onAdd(e, data); - } - }); }, _onDragOver: function (e) { - var dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer; - if (this._trigger('dragover', e) === false) { - return false; - } - if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1) { - dataTransfer.dropEffect = 'copy'; + e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer; + var dataTransfer = e.dataTransfer; + if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 && + this._trigger( + 'dragover', + $.Event('dragover', { delegatedEvent: e }) + ) !== false) { e.preventDefault(); + dataTransfer.dropEffect = 'copy'; } }, @@ -1096,9 +1266,11 @@ paste: this._onPaste }); } - this._on(this.options.fileInput, { - change: this._onChange - }); + if ($.support.fileInput) { + this._on(this.options.fileInput, { + change: this._onChange + }); + } }, _destroyEventHandlers: function () { @@ -1108,12 +1280,12 @@ }, _setOption: function (key, value) { - var refresh = $.inArray(key, this._refreshOptionsList) !== -1; - if (refresh) { + var reinit = $.inArray(key, this._specialOptions) !== -1; + if (reinit) { this._destroyEventHandlers(); } this._super(key, value); - if (refresh) { + if (reinit) { this._initSpecialOptions(); this._initEventHandlers(); } @@ -1135,10 +1307,41 @@ } }, - _create: function () { - var options = this.options; + _getRegExp: function (str) { + var parts = str.split('/'), + modifiers = parts.pop(); + parts.shift(); + return new RegExp(parts.join('/'), modifiers); + }, + + _isRegExpOption: function (key, value) { + return key !== 'url' && $.type(value) === 'string' && + /^\/.*\/[igm]{0,3}$/.test(value); + }, + + _initDataAttributes: function () { + var that = this, + options = this.options, + clone = $(this.element[0].cloneNode(false)); // Initialize options set via HTML5 data-attributes: - $.extend(options, $(this.element[0].cloneNode(false)).data()); + $.each( + clone.data(), + function (key, value) { + var dataAttributeName = 'data-' + + // Convert camelCase to hyphen-ated key: + key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); + if (clone.attr(dataAttributeName)) { + if (that._isRegExpOption(key, value)) { + value = that._getRegExp(value); + } + options[key] = value; + } + } + ); + }, + + _create: function () { + this._initDataAttributes(); this._initSpecialOptions(); this._slots = []; this._sequence = this._getXHRPromise(true); @@ -1207,8 +1410,13 @@ if (aborted) { return; } + if (!files.length) { + dfd.reject(); + return; + } data.files = files; - jqXHR = that._onSend(null, data).then( + jqXHR = that._onSend(null, data); + jqXHR.then( function (result, textStatus, jqXHR) { dfd.resolve(result, textStatus, jqXHR); }, @@ -1230,4 +1438,4 @@ }); -})); +})); \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.fileupload.min.js b/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.fileupload.min.js index bdf43cc44..28e25e907 100644 --- a/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.fileupload.min.js +++ b/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.fileupload.min.js @@ -1,2 +1 @@ -(function(n){"use strict";typeof define=="function"&&define.amd?define(["jquery","jquery.ui.widget"],n):n(window.jQuery)})(function(n){"use strict";n.support.xhrFileUpload=!!(window.XMLHttpRequestUpload&&window.FileReader),n.support.xhrFormDataFileUpload=!!window.FormData,n.widget("blueimp.fileupload",{options:{dropZone:n(document),pasteZone:n(document),fileInput:undefined,replaceFileInput:!0,paramName:undefined,singleFileUploads:!0,limitMultiFileUploads:undefined,sequentialUploads:!1,limitConcurrentUploads:undefined,forceIframeTransport:!1,redirect:undefined,redirectParamName:undefined,postMessage:undefined,multipart:!0,maxChunkSize:undefined,uploadedBytes:undefined,recalculateProgress:!0,progressInterval:100,bitrateInterval:500,autoUpload:!0,formData:function(n){return n.serializeArray()},add:function(t,i){(i.autoUpload||i.autoUpload!==!1&&(n(this).data("blueimp-fileupload")||n(this).data("fileupload")).options.autoUpload)&&i.submit()},processData:!1,contentType:!1,cache:!1},_refreshOptionsList:["fileInput","dropZone","pasteZone","multipart","forceIframeTransport"],_BitrateTimer:function(){this.timestamp=Date.now?Date.now():(new Date).getTime(),this.loaded=0,this.bitrate=0,this.getBitrate=function(n,t,i){var r=n-this.timestamp;return(!this.bitrate||!i||r>i)&&(this.bitrate=(t-this.loaded)*(1e3/r)*8,this.loaded=t,this.timestamp=n),this.bitrate}},_isXHRUpload:function(t){return!t.forceIframeTransport&&(!t.multipart&&n.support.xhrFileUpload||n.support.xhrFormDataFileUpload)},_getFormData:function(t){var i;return typeof t.formData=="function"?t.formData(t.form):n.isArray(t.formData)?t.formData:n.type(t.formData)==="object"?(i=[],n.each(t.formData,function(n,t){i.push({name:n,value:t})}),i):[]},_getTotal:function(t){var i=0;return n.each(t,function(n,t){i+=t.size||1}),i},_initProgressObject:function(t){var i={loaded:0,total:0,bitrate:0};t._progress?n.extend(t._progress,i):t._progress=i},_initResponseObject:function(n){var t;if(n._response)for(t in n._response)n._response.hasOwnProperty(t)&&delete n._response[t];else n._response={}},_onProgress:function(n,t){if(n.lengthComputable){var i=Date.now?Date.now():(new Date).getTime(),r;if(t._time&&t.progressInterval&&i-t._time<\/a>").prop("href",t.url).prop("host")!==location.host&&t.formData.push({name:t.redirectParamName||"redirect",value:t.redirect})},_initDataSettings:function(n){this._isXHRUpload(n)?(this._chunkedUpload(n,!0)||(n.data||this._initXHRData(n),this._initProgressListener(n)),n.postMessage&&(n.dataType="postmessage "+(n.dataType||""))):this._initIframeSettings(n,"iframe")},_getParamName:function(t){var r=n(t.fileInput),i=t.paramName;return i?n.isArray(i)||(i=[i]):(i=[],r.each(function(){for(var t=n(this),u=t.prop("name")||"files[]",r=(t.prop("files")||[1]).length;r;)i.push(u),r-=1}),i.length||(i=[r.prop("name")||"files[]"])),i},_initFormSettings:function(t){t.form&&t.form.length||(t.form=n(t.fileInput.prop("form")),t.form.length||(t.form=n(this.options.fileInput.prop("form")))),t.paramName=this._getParamName(t),t.url||(t.url=t.form.prop("action")||location.href),t.type=(t.type||t.form.prop("method")||"").toUpperCase(),t.type!=="POST"&&t.type!=="PUT"&&t.type!=="PATCH"&&(t.type="POST"),t.formAcceptCharset||(t.formAcceptCharset=t.form.attr("accept-charset"))},_getAJAXSettings:function(t){var i=n.extend({},this.options,t);return this._initFormSettings(i),this._initDataSettings(i),i},_getDeferredState:function(n){return n.state?n.state():n.isResolved()?"resolved":n.isRejected()?"rejected":"pending"},_enhancePromise:function(n){return n.success=n.done,n.error=n.fail,n.complete=n.always,n},_getXHRPromise:function(t,i,r){var u=n.Deferred(),f=u.promise();return i=i||this.options.context||f,t===!0?u.resolveWith(i,r):t===!1&&u.rejectWith(i,r),f.abort=u.promise,this._enhancePromise(f)},_addConvenienceMethods:function(n,t){var i=this;t.submit=function(){return this.state()!=="pending"&&(t.jqXHR=this.jqXHR=i._trigger("submit",n,this)!==!1&&i._onSend(n,this)),this.jqXHR||i._getXHRPromise()},t.abort=function(){return this.jqXHR?this.jqXHR.abort():i._getXHRPromise()},t.state=function(){if(this.jqXHR)return i._getDeferredState(this.jqXHR)},t.progress=function(){return this._progress},t.response=function(){return this._response}},_getUploadedBytes:function(n){var i=n.getResponseHeader("Range"),t=i&&i.split("-"),r=t&&t.length>1&&parseInt(t[1],10);return r&&r+1},_chunkedUpload:function(t,i){var u=this,f=t.files[0],e=f.size,r=t.uploadedBytes=t.uploadedBytes||0,c=t.maxChunkSize||e,l=f.slice||f.webkitSlice||f.mozSlice,o=n.Deferred(),s=o.promise(),a,h;return!(this._isXHRUpload(t)&&l&&(r||c=e?(f.error="Uploaded bytes exceed file size",this._getXHRPromise(!1,t.context,[null,"error",f.error])):(h=function(){var i=n.extend({},t),s=i._progress.loaded;i.blob=l.call(f,r,r+c,f.type),i.chunkSize=i.blob.size,i.contentRange="bytes "+r+"-"+(r+i.chunkSize-1)+"/"+e,u._initXHRData(i),u._initProgressListener(i),a=(u._trigger("chunksend",null,i)!==!1&&n.ajax(i)||u._getXHRPromise(!1,i.context)).done(function(f,c,l){r=u._getUploadedBytes(l)||r+i.chunkSize,i._progress.loaded===s&&u._onProgress(n.Event("progress",{lengthComputable:!0,loaded:r-i.uploadedBytes,total:r-i.uploadedBytes}),i),t.uploadedBytes=i.uploadedBytes=r,i.result=f,i.textStatus=c,i.jqXHR=l,u._trigger("chunkdone",null,i),u._trigger("chunkalways",null,i),rr._sending)for(var f=r._slots.shift();f;){if(r._getDeferredState(f)==="pending"){f.resolve();break}f=r._slots.shift()}r._active===0&&r._trigger("stop")})};return(this._beforeSend(t,u),this.options.sequentialUploads||this.options.limitConcurrentUploads&&this.options.limitConcurrentUploads<=this._sending)?(this.options.limitConcurrentUploads>1?(e=n.Deferred(),this._slots.push(e),h=e.pipe(o)):h=this._sequence=this._sequence.pipe(o,o),h.abort=function(){return(s=[undefined,"abort","abort"],!f)?(e&&e.rejectWith(u.context,s),o()):f.abort()},this._enhancePromise(h)):o()},_onAdd:function(t,i){var s=this,l=!0,u=n.extend({},this.options,i),f=u.limitMultiFileUploads,h=this._getParamName(u),e,c,o,r;if((u.singleFileUploads||f)&&this._isXHRUpload(u))if(!u.singleFileUploads&&f)for(o=[],e=[],r=0;r<\/form>").append(i)[0].reset(),t.after(i).detach(),n.cleanData(t.unbind("remove")),this.options.fileInput=this.options.fileInput.map(function(n,r){return r===t[0]?i[0]:r}),t[0]===this.element[0]&&(this.element=i)},_handleFileTreeEntry:function(t,i){var e=this,r=n.Deferred(),u=function(n){n&&!n.entry&&(n.entry=t),r.resolve([n])},f;return i=i||"",t.isFile?t._file?(t._file.relativePath=i,r.resolve(t._file)):t.file(function(n){n.relativePath=i,r.resolve(n)},u):t.isDirectory?(f=t.createReader(),f.readEntries(function(n){e._handleFileTreeEntries(n,i+t.name+"/").done(function(n){r.resolve(n)}).fail(u)},u)):r.resolve([]),r.promise()},_handleFileTreeEntries:function(t,i){var r=this;return n.when.apply(n,n.map(t,function(n){return r._handleFileTreeEntry(n,i)})).pipe(function(){return Array.prototype.concat.apply([],arguments)})},_getDroppedFiles:function(t){t=t||{};var i=t.items;return i&&i.length&&(i[0].webkitGetAsEntry||i[0].getAsEntry)?this._handleFileTreeEntries(n.map(i,function(n){var t;return n.webkitGetAsEntry?(t=n.webkitGetAsEntry(),t&&(t._file=n.getAsFile()),t):n.getAsEntry()})):n.Deferred().resolve(n.makeArray(t.files)).promise()},_getSingleFileInputFiles:function(t){t=n(t);var r=t.prop("webkitEntries")||t.prop("entries"),i,u;if(r&&r.length)return this._handleFileTreeEntries(r);if(i=n.makeArray(t.prop("files")),i.length)i[0].name===undefined&&i[0].fileName&&n.each(i,function(n,t){t.name=t.fileName,t.size=t.fileSize});else{if(u=t.prop("value"),!u)return n.Deferred().resolve([]).promise();i=[{name:u.replace(/^.*\\/,"")}]}return n.Deferred().resolve(i).promise()},_getFileInputFiles:function(t){return!(t instanceof n)||t.length===1?this._getSingleFileInputFiles(t):n.when.apply(n,n.map(t,this._getSingleFileInputFiles)).pipe(function(){return Array.prototype.concat.apply([],arguments)})},_onChange:function(t){var r=this,i={fileInput:n(t.target),form:n(t.target.form)};this._getFileInputFiles(i.fileInput).always(function(n){i.files=n,r.options.replaceFileInput&&r._replaceFileInput(i.fileInput),r._trigger("change",t,i)!==!1&&r._onAdd(t,i)})},_onPaste:function(t){var r=t.originalEvent.clipboardData,u=r&&r.items||[],i={files:[]};return n.each(u,function(n,t){var r=t.getAsFile&&t.getAsFile();r&&i.files.push(r)}),this._trigger("paste",t,i)===!1||this._onAdd(t,i)===!1?!1:void 0},_onDrop:function(n){var r=this,t=n.dataTransfer=n.originalEvent.dataTransfer,i={};t&&t.files&&t.files.length&&n.preventDefault(),this._getDroppedFiles(t).always(function(t){i.files=t,r._trigger("drop",n,i)!==!1&&r._onAdd(n,i)})},_onDragOver:function(t){var i=t.dataTransfer=t.originalEvent.dataTransfer;if(this._trigger("dragover",t)===!1)return!1;i&&n.inArray("Files",i.types)!==-1&&(i.dropEffect="copy",t.preventDefault())},_initEventHandlers:function(){this._isXHRUpload(this.options)&&(this._on(this.options.dropZone,{dragover:this._onDragOver,drop:this._onDrop}),this._on(this.options.pasteZone,{paste:this._onPaste})),this._on(this.options.fileInput,{change:this._onChange})},_destroyEventHandlers:function(){this._off(this.options.dropZone,"dragover drop"),this._off(this.options.pasteZone,"paste"),this._off(this.options.fileInput,"change")},_setOption:function(t,i){var r=n.inArray(t,this._refreshOptionsList)!==-1;r&&this._destroyEventHandlers(),this._super(t,i),r&&(this._initSpecialOptions(),this._initEventHandlers())},_initSpecialOptions:function(){var t=this.options;t.fileInput===undefined?t.fileInput=this.element.is('input[type="file"]')?this.element:this.element.find('input[type="file"]'):t.fileInput instanceof n||(t.fileInput=n(t.fileInput)),t.dropZone instanceof n||(t.dropZone=n(t.dropZone)),t.pasteZone instanceof n||(t.pasteZone=n(t.pasteZone))},_create:function(){var t=this.options;n.extend(t,n(this.element[0].cloneNode(!1)).data()),this._initSpecialOptions(),this._slots=[],this._sequence=this._getXHRPromise(!0),this._sending=this._active=0,this._initProgressObject(this),this._initEventHandlers()},active:function(){return this._active},progress:function(){return this._progress},add:function(t){var i=this;t&&!this.options.disabled&&(t.fileInput&&!t.files?this._getFileInputFiles(t.fileInput).always(function(n){t.files=n,i._onAdd(null,t)}):(t.files=n.makeArray(t.files),this._onAdd(null,t)))},send:function(t){if(t&&!this.options.disabled){if(t.fileInput&&!t.files){var e=this,i=n.Deferred(),r=i.promise(),u,f;return r.abort=function(){return(f=!0,u)?u.abort():(i.reject(null,"abort","abort"),r)},this._getFileInputFiles(t.fileInput).always(function(n){f||(t.files=n,u=e._onSend(null,t).then(function(n,t,r){i.resolve(n,t,r)},function(n,t,r){i.reject(n,t,r)}))}),this._enhancePromise(r)}if(t.files=n.makeArray(t.files),t.files.length)return this._onSend(null,t)}return this._getXHRPromise(!1,t&&t.context)}})}); -//@ sourceMappingURL=jquery.fileupload.min.js.map \ No newline at end of file +(function(n){"use strict";typeof define=="function"&&define.amd?define(["jquery","jquery.ui.widget"],n):n(window.jQuery)})(function(n){"use strict";n.support.fileInput=!(new RegExp("(Android (1\\.[0156]|2\\.[01]))|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)|(w(eb)?OSBrowser)|(webOS)|(Kindle/(1\\.0|2\\.[05]|3\\.0))").test(window.navigator.userAgent)||n('').prop("disabled"));n.support.xhrFileUpload=!!(window.ProgressEvent&&window.FileReader);n.support.xhrFormDataFileUpload=!!window.FormData;n.support.blobSlice=window.Blob&&(Blob.prototype.slice||Blob.prototype.webkitSlice||Blob.prototype.mozSlice);n.widget("blueimp.fileupload",{options:{dropZone:n(document),pasteZone:n(document),fileInput:undefined,replaceFileInput:!0,paramName:undefined,singleFileUploads:!0,limitMultiFileUploads:undefined,limitMultiFileUploadSize:undefined,limitMultiFileUploadSizeOverhead:512,sequentialUploads:!1,limitConcurrentUploads:undefined,forceIframeTransport:!1,redirect:undefined,redirectParamName:undefined,postMessage:undefined,multipart:!0,maxChunkSize:undefined,uploadedBytes:undefined,recalculateProgress:!0,progressInterval:100,bitrateInterval:500,autoUpload:!0,messages:{uploadedBytes:"Uploaded bytes exceed file size"},i18n:function(t,i){return t=this.messages[t]||t.toString(),i&&n.each(i,function(n,i){t=t.replace("{"+n+"}",i)}),t},formData:function(n){return n.serializeArray()},add:function(t,i){if(t.isDefaultPrevented())return!1;(i.autoUpload||i.autoUpload!==!1&&n(this).fileupload("option","autoUpload"))&&i.process().done(function(){i.submit()})},processData:!1,contentType:!1,cache:!1},_specialOptions:["fileInput","dropZone","pasteZone","multipart","forceIframeTransport"],_blobSlice:n.support.blobSlice&&function(){var n=this.slice||this.webkitSlice||this.mozSlice;return n.apply(this,arguments)},_BitrateTimer:function(){this.timestamp=Date.now?Date.now():(new Date).getTime();this.loaded=0;this.bitrate=0;this.getBitrate=function(n,t,i){var r=n-this.timestamp;return(!this.bitrate||!i||r>i)&&(this.bitrate=(t-this.loaded)*(1e3/r)*8,this.loaded=t,this.timestamp=n),this.bitrate}},_isXHRUpload:function(t){return!t.forceIframeTransport&&(!t.multipart&&n.support.xhrFileUpload||n.support.xhrFormDataFileUpload)},_getFormData:function(t){var i;return n.type(t.formData)==="function"?t.formData(t.form):n.isArray(t.formData)?t.formData:n.type(t.formData)==="object"?(i=[],n.each(t.formData,function(n,t){i.push({name:n,value:t})}),i):[]},_getTotal:function(t){var i=0;return n.each(t,function(n,t){i+=t.size||1}),i},_initProgressObject:function(t){var i={loaded:0,total:0,bitrate:0};t._progress?n.extend(t._progress,i):t._progress=i},_initResponseObject:function(n){var t;if(n._response)for(t in n._response)n._response.hasOwnProperty(t)&&delete n._response[t];else n._response={}},_onProgress:function(t,i){if(t.lengthComputable){var r=Date.now?Date.now():(new Date).getTime(),u;if(i._time&&i.progressInterval&&r-i._time<\/a>").prop("href",t.url).prop("host");t.dataType="iframe "+(t.dataType||"");t.formData=this._getFormData(t);t.redirect&&i&&i!==location.host&&t.formData.push({name:t.redirectParamName||"redirect",value:t.redirect})},_initDataSettings:function(n){this._isXHRUpload(n)?(this._chunkedUpload(n,!0)||(n.data||this._initXHRData(n),this._initProgressListener(n)),n.postMessage&&(n.dataType="postmessage "+(n.dataType||""))):this._initIframeSettings(n)},_getParamName:function(t){var r=n(t.fileInput),i=t.paramName;return i?n.isArray(i)||(i=[i]):(i=[],r.each(function(){for(var t=n(this),u=t.prop("name")||"files[]",r=(t.prop("files")||[1]).length;r;)i.push(u),r-=1}),i.length||(i=[r.prop("name")||"files[]"])),i},_initFormSettings:function(t){t.form&&t.form.length||(t.form=n(t.fileInput.prop("form")),t.form.length||(t.form=n(this.options.fileInput.prop("form"))));t.paramName=this._getParamName(t);t.url||(t.url=t.form.prop("action")||location.href);t.type=(t.type||n.type(t.form.prop("method"))==="string"&&t.form.prop("method")||"").toUpperCase();t.type!=="POST"&&t.type!=="PUT"&&t.type!=="PATCH"&&(t.type="POST");t.formAcceptCharset||(t.formAcceptCharset=t.form.attr("accept-charset"))},_getAJAXSettings:function(t){var i=n.extend({},this.options,t);return this._initFormSettings(i),this._initDataSettings(i),i},_getDeferredState:function(n){return n.state?n.state():n.isResolved()?"resolved":n.isRejected()?"rejected":"pending"},_enhancePromise:function(n){return n.success=n.done,n.error=n.fail,n.complete=n.always,n},_getXHRPromise:function(t,i,r){var u=n.Deferred(),f=u.promise();return i=i||this.options.context||f,t===!0?u.resolveWith(i,r):t===!1&&u.rejectWith(i,r),f.abort=u.promise,this._enhancePromise(f)},_addConvenienceMethods:function(t,i){var r=this,u=function(t){return n.Deferred().resolveWith(r,t).promise()};i.process=function(t,f){return(t||f)&&(i._processQueue=this._processQueue=(this._processQueue||u([this])).pipe(function(){return i.errorThrown?n.Deferred().rejectWith(r,[i]).promise():u(arguments)}).pipe(t,f)),this._processQueue||u([this])};i.submit=function(){return this.state()!=="pending"&&(i.jqXHR=this.jqXHR=r._trigger("submit",n.Event("submit",{delegatedEvent:t}),this)!==!1&&r._onSend(t,this)),this.jqXHR||r._getXHRPromise()};i.abort=function(){return this.jqXHR?this.jqXHR.abort():(this.errorThrown="abort",r._trigger("fail",null,this),r._getXHRPromise(!1))};i.state=function(){return this.jqXHR?r._getDeferredState(this.jqXHR):this._processQueue?r._getDeferredState(this._processQueue):void 0};i.processing=function(){return!this.jqXHR&&this._processQueue&&r._getDeferredState(this._processQueue)==="pending"};i.progress=function(){return this._progress};i.response=function(){return this._response}},_getUploadedBytes:function(n){var i=n.getResponseHeader("Range"),t=i&&i.split("-"),r=t&&t.length>1&&parseInt(t[1],10);return r&&r+1},_chunkedUpload:function(t,i){t.uploadedBytes=t.uploadedBytes||0;var u=this,f=t.files[0],e=f.size,r=t.uploadedBytes,c=t.maxChunkSize||e,l=this._blobSlice,o=n.Deferred(),s=o.promise(),a,h;return!(this._isXHRUpload(t)&&l&&(r||c=e?(f.error=t.i18n("uploadedBytes"),this._getXHRPromise(!1,t.context,[null,"error",f.error])):(h=function(){var i=n.extend({},t),s=i._progress.loaded;i.blob=l.call(f,r,r+c,f.type);i.chunkSize=i.blob.size;i.contentRange="bytes "+r+"-"+(r+i.chunkSize-1)+"/"+e;u._initXHRData(i);u._initProgressListener(i);a=(u._trigger("chunksend",null,i)!==!1&&n.ajax(i)||u._getXHRPromise(!1,i.context)).done(function(f,c,l){r=u._getUploadedBytes(l)||r+i.chunkSize;s+i.chunkSize-i._progress.loaded&&u._onProgress(n.Event("progress",{lengthComputable:!0,loaded:r-i.uploadedBytes,total:r-i.uploadedBytes}),i);t.uploadedBytes=i.uploadedBytes=r;i.result=f;i.textStatus=c;i.jqXHR=l;u._trigger("chunkdone",null,i);u._trigger("chunkalways",null,i);rr._sending)for(var f=r._slots.shift();f;){if(r._getDeferredState(f)==="pending"){f.resolve();break}f=r._slots.shift()}r._active===0&&r._trigger("stop")})};return(this._beforeSend(t,u),this.options.sequentialUploads||this.options.limitConcurrentUploads&&this.options.limitConcurrentUploads<=this._sending)?(this.options.limitConcurrentUploads>1?(e=n.Deferred(),this._slots.push(e),h=e.pipe(o)):(this._sequence=this._sequence.pipe(o,o),h=this._sequence),h.abort=function(){return(s=[undefined,"abort","abort"],!f)?(e&&e.rejectWith(u.context,s),o()):f.abort()},this._enhancePromise(h)):o()},_onAdd:function(t,i){var a=this,p=!0,f=n.extend({},this.options,i),u=i.files,v=u.length,o=f.limitMultiFileUploads,c=f.limitMultiFileUploadSize,b=f.limitMultiFileUploadSizeOverhead,w=0,l=this._getParamName(f),s,e,h,r,y=0;if(c&&(!v||u[0].size===undefined)&&(c=undefined),(f.singleFileUploads||o||c)&&this._isXHRUpload(f))if(f.singleFileUploads||c||!o)if(!f.singleFileUploads&&c)for(h=[],s=[],r=0;rc||o&&r+1-y>=o)&&(h.push(u.slice(y,r+1)),e=l.slice(y,r+1),e.length||(e=l),s.push(e),y=r+1,w=0);else s=l;else for(h=[],s=[],r=0;r<\/form>").append(r)[0].reset();i.after(r).detach();n.cleanData(i.unbind("remove"));this.options.fileInput=this.options.fileInput.map(function(n,t){return t===i[0]?r[0]:t});i[0]===this.element[0]&&(this.element=r)},_handleFileTreeEntry:function(t,i){var s=this,r=n.Deferred(),u=function(n){n&&!n.entry&&(n.entry=t);r.resolve([n])},h=function(n){s._handleFileTreeEntries(n,i+t.name+"/").done(function(n){r.resolve(n)}).fail(u)},e=function(){o.readEntries(function(n){n.length?(f=f.concat(n),e()):h(f)},u)},o,f=[];return i=i||"",t.isFile?t._file?(t._file.relativePath=i,r.resolve(t._file)):t.file(function(n){n.relativePath=i;r.resolve(n)},u):t.isDirectory?(o=t.createReader(),e()):r.resolve([]),r.promise()},_handleFileTreeEntries:function(t,i){var r=this;return n.when.apply(n,n.map(t,function(n){return r._handleFileTreeEntry(n,i)})).pipe(function(){return Array.prototype.concat.apply([],arguments)})},_getDroppedFiles:function(t){t=t||{};var i=t.items;return i&&i.length&&(i[0].webkitGetAsEntry||i[0].getAsEntry)?this._handleFileTreeEntries(n.map(i,function(n){var t;return n.webkitGetAsEntry?(t=n.webkitGetAsEntry(),t&&(t._file=n.getAsFile()),t):n.getAsEntry()})):n.Deferred().resolve(n.makeArray(t.files)).promise()},_getSingleFileInputFiles:function(t){t=n(t);var r=t.prop("webkitEntries")||t.prop("entries"),i,u;if(r&&r.length)return this._handleFileTreeEntries(r);if(i=n.makeArray(t.prop("files")),i.length)i[0].name===undefined&&i[0].fileName&&n.each(i,function(n,t){t.name=t.fileName;t.size=t.fileSize});else{if(u=t.prop("value"),!u)return n.Deferred().resolve([]).promise();i=[{name:u.replace(/^.*\\/,"")}]}return n.Deferred().resolve(i).promise()},_getFileInputFiles:function(t){return!(t instanceof n)||t.length===1?this._getSingleFileInputFiles(t):n.when.apply(n,n.map(t,this._getSingleFileInputFiles)).pipe(function(){return Array.prototype.concat.apply([],arguments)})},_onChange:function(t){var r=this,i={fileInput:n(t.target),form:n(t.target.form)};this._getFileInputFiles(i.fileInput).always(function(u){i.files=u;r.options.replaceFileInput&&r._replaceFileInput(i);r._trigger("change",n.Event("change",{delegatedEvent:t}),i)!==!1&&r._onAdd(t,i)})},_onPaste:function(t){var i=t.originalEvent&&t.originalEvent.clipboardData&&t.originalEvent.clipboardData.items,r={files:[]};i&&i.length&&(n.each(i,function(n,t){var i=t.getAsFile&&t.getAsFile();i&&r.files.push(i)}),this._trigger("paste",n.Event("paste",{delegatedEvent:t}),r)!==!1&&this._onAdd(t,r))},_onDrop:function(t){t.dataTransfer=t.originalEvent&&t.originalEvent.dataTransfer;var u=this,i=t.dataTransfer,r={};i&&i.files&&i.files.length&&(t.preventDefault(),this._getDroppedFiles(i).always(function(i){r.files=i;u._trigger("drop",n.Event("drop",{delegatedEvent:t}),r)!==!1&&u._onAdd(t,r)}))},_onDragOver:function(t){t.dataTransfer=t.originalEvent&&t.originalEvent.dataTransfer;var i=t.dataTransfer;i&&n.inArray("Files",i.types)!==-1&&this._trigger("dragover",n.Event("dragover",{delegatedEvent:t}))!==!1&&(t.preventDefault(),i.dropEffect="copy")},_initEventHandlers:function(){this._isXHRUpload(this.options)&&(this._on(this.options.dropZone,{dragover:this._onDragOver,drop:this._onDrop}),this._on(this.options.pasteZone,{paste:this._onPaste}));n.support.fileInput&&this._on(this.options.fileInput,{change:this._onChange})},_destroyEventHandlers:function(){this._off(this.options.dropZone,"dragover drop");this._off(this.options.pasteZone,"paste");this._off(this.options.fileInput,"change")},_setOption:function(t,i){var r=n.inArray(t,this._specialOptions)!==-1;r&&this._destroyEventHandlers();this._super(t,i);r&&(this._initSpecialOptions(),this._initEventHandlers())},_initSpecialOptions:function(){var t=this.options;t.fileInput===undefined?t.fileInput=this.element.is('input[type="file"]')?this.element:this.element.find('input[type="file"]'):t.fileInput instanceof n||(t.fileInput=n(t.fileInput));t.dropZone instanceof n||(t.dropZone=n(t.dropZone));t.pasteZone instanceof n||(t.pasteZone=n(t.pasteZone))},_getRegExp:function(n){var t=n.split("/"),i=t.pop();return t.shift(),new RegExp(t.join("/"),i)},_isRegExpOption:function(t,i){return t!=="url"&&n.type(i)==="string"&&/^\/.*\/[igm]{0,3}$/.test(i)},_initDataAttributes:function(){var t=this,r=this.options,i=n(this.element[0].cloneNode(!1));n.each(i.data(),function(n,u){var f="data-"+n.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();i.attr(f)&&(t._isRegExpOption(n,u)&&(u=t._getRegExp(u)),r[n]=u)})},_create:function(){this._initDataAttributes();this._initSpecialOptions();this._slots=[];this._sequence=this._getXHRPromise(!0);this._sending=this._active=0;this._initProgressObject(this);this._initEventHandlers()},active:function(){return this._active},progress:function(){return this._progress},add:function(t){var i=this;t&&!this.options.disabled&&(t.fileInput&&!t.files?this._getFileInputFiles(t.fileInput).always(function(n){t.files=n;i._onAdd(null,t)}):(t.files=n.makeArray(t.files),this._onAdd(null,t)))},send:function(t){if(t&&!this.options.disabled){if(t.fileInput&&!t.files){var e=this,i=n.Deferred(),u=i.promise(),r,f;return u.abort=function(){return(f=!0,r)?r.abort():(i.reject(null,"abort","abort"),u)},this._getFileInputFiles(t.fileInput).always(function(n){if(!f){if(!n.length){i.reject();return}t.files=n;r=e._onSend(null,t);r.then(function(n,t,r){i.resolve(n,t,r)},function(n,t,r){i.reject(n,t,r)})}}),this._enhancePromise(u)}if(t.files=n.makeArray(t.files),t.files.length)return this._onSend(null,t)}return this._getXHRPromise(!1,t&&t.context)}})}); \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.iframe-transport.js b/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.iframe-transport.js index ed2589506..32f3920e8 100644 --- a/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.iframe-transport.js +++ b/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.iframe-transport.js @@ -1,5 +1,5 @@ /* - * jQuery Iframe Transport Plugin 1.6.1 + * jQuery Iframe Transport Plugin 1.8.2 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2011, Sebastian Tschan @@ -9,8 +9,7 @@ * http://www.opensource.org/licenses/MIT */ -/*jslint unparam: true, nomen: true */ -/*global define, window, document */ +/* global define, window, document */ (function (factory) { 'use strict'; @@ -27,7 +26,7 @@ // Helper variable to create unique names for the transport iframes: var counter = 0; - // The iframe transport accepts three additional options: + // The iframe transport accepts four additional options: // options.fileInput: a jQuery collection of file input fields // options.paramName: the parameter name for the file form data, // overrides the name property of the file input field(s), @@ -35,9 +34,16 @@ // options.formData: an array of objects with name and value properties, // equivalent to the return data of .serializeArray(), e.g.: // [{name: 'a', value: 1}, {name: 'b', value: 2}] + // options.initialIframeSrc: the URL of the initial iframe src, + // by default set to "javascript:false;" $.ajaxTransport('iframe', function (options) { if (options.async) { - var form, + // javascript:false as initial iframe src + // prevents warning popups on HTTPS in IE6: + /*jshint scripturl: true */ + var initialIframeSrc = options.initialIframeSrc || 'javascript:false;', + /*jshint scripturl: false */ + form, iframe, addParamChar; return { @@ -56,14 +62,13 @@ options.url = options.url + addParamChar + '_method=PATCH'; options.type = 'POST'; } - // javascript:false as initial iframe src - // prevents warning popups on HTTPS in IE6. // IE versions below IE8 cannot set the name property of // elements that have already been added to the DOM, // so we set the name along with the iframe HTML markup: + counter += 1; iframe = $( - '' + '' ).bind('load', function () { var fileInputClones, paramNames = $.isArray(options.paramName) ? @@ -90,13 +95,18 @@ completeCallback( 200, 'success', - {'iframe': response} + { 'iframe': response } ); // Fix for IE endless progress bar activity bug // (happens on form submits to iframe targets): - $('') + $('') .appendTo(form); - form.remove(); + window.setTimeout(function () { + // Removing the form in a setTimeout call + // allows Chrome's developer tools to display + // the response result + form.remove(); + }, 0); }); form .prop('target', iframe.prop('name')) @@ -132,6 +142,8 @@ .prop('enctype', 'multipart/form-data') // enctype must be set as encoding for IE: .prop('encoding', 'multipart/form-data'); + // Remove the HTML5 form attribute from the input(s): + options.fileInput.removeAttr('form'); } form.submit(); // Insert the file input fields at their original location @@ -139,7 +151,10 @@ if (fileInputClones && fileInputClones.length) { options.fileInput.each(function (index, input) { var clone = $(fileInputClones[index]); - $(input).prop('name', clone.prop('name')); + // Restore the original name and form properties: + $(input) + .prop('name', clone.prop('name')) + .attr('form', clone.attr('form')); clone.replaceWith(input); }); } @@ -153,7 +168,7 @@ // concat is used to avoid the "Script URL" JSLint error: iframe .unbind('load') - .prop('src', 'javascript'.concat(':false;')); + .prop('src', initialIframeSrc); } if (form) { form.remove(); @@ -164,7 +179,15 @@ }); // The iframe transport returns the iframe content document as response. - // The following adds converters from iframe to text, json, html, and script: + // The following adds converters from iframe to text, json, html, xml + // and script. + // Please note that the Content-Type for JSON responses has to be text/plain + // or text/html, if the browser doesn't include application/json in the + // Accept header, else IE will show a download dialog. + // The Content-Type for XML responses on the other hand has to be always + // application/xml or text/xml, so IE properly parses the XML response. + // See also + // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation $.ajaxSetup({ converters: { 'iframe text': function (iframe) { @@ -176,10 +199,16 @@ 'iframe html': function (iframe) { return iframe && $(iframe[0].body).html(); }, + 'iframe xml': function (iframe) { + var xmlDoc = iframe && iframe[0]; + return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc : + $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) || + $(xmlDoc.body).html()); + }, 'iframe script': function (iframe) { return iframe && $.globalEval($(iframe[0].body).text()); } } }); -})); +})); \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.iframe-transport.min.js b/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.iframe-transport.min.js index 9172a8e1d..7123b4075 100644 --- a/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.iframe-transport.min.js +++ b/src/Orchard.Web/Modules/Orchard.jQuery/Scripts/jquery.iframe-transport.min.js @@ -1,2 +1 @@ -(function(n){"use strict";typeof define=="function"&&define.amd?define(["jquery"],n):n(window.jQuery)})(function(n){"use strict";var t=0;n.ajaxTransport("iframe",function(i){if(i.async){var r,u,f;return{send:function(e,o){r=n('
<\/form>'),r.attr("accept-charset",i.formAcceptCharset),f=/\?/.test(i.url)?"&":"?",i.type==="DELETE"?(i.url=i.url+f+"_method=DELETE",i.type="POST"):i.type==="PUT"?(i.url=i.url+f+"_method=PUT",i.type="POST"):i.type==="PATCH"&&(i.url=i.url+f+"_method=PATCH",i.type="POST"),u=n('