vendor/assets/javascripts/uploader/jquery.fileupload-ui.js in rails-uploader-0.2.8 vs vendor/assets/javascripts/uploader/jquery.fileupload-ui.js in rails-uploader-0.3.0
- old
+ new
@@ -1,72 +1,62 @@
/*
- * jQuery File Upload User Interface Plugin 7.4.4
+ * jQuery File Upload User Interface Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
*/
-/*jslint nomen: true, unparam: true, regexp: true */
-/*global define, window, URL, webkitURL, FileReader */
+/* jshint nomen:false */
+/* global define, require, window */
-(function (factory) {
+;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define([
'jquery',
'tmpl',
- 'load-image',
- './jquery.fileupload-fp'
+ './jquery.fileupload-image',
+ './jquery.fileupload-audio',
+ './jquery.fileupload-video',
+ './jquery.fileupload-validate'
], factory);
+ } else if (typeof exports === 'object') {
+ // Node/CommonJS:
+ factory(
+ require('jquery'),
+ require('tmpl')
+ );
} else {
// Browser globals:
factory(
window.jQuery,
- window.tmpl,
- window.loadImage
+ window.tmpl
);
}
-}(function ($, tmpl, loadImage) {
+}(function ($, tmpl) {
'use strict';
+ $.blueimp.fileupload.prototype._specialOptions.push(
+ 'filesContainer',
+ 'uploadTemplateId',
+ 'downloadTemplateId'
+ );
+
// The UI version extends the file upload widget
// and adds complete user interface interaction:
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
options: {
// By default, files added to the widget are uploaded as soon
// as the user clicks on the start buttons. To enable automatic
// uploads, set the following option to true:
autoUpload: false,
- // The following option limits the number of files that are
- // allowed to be uploaded using this widget:
- maxNumberOfFiles: undefined,
- // The maximum allowed file size:
- maxFileSize: undefined,
- // The minimum allowed file size:
- minFileSize: undefined,
- // The regular expression for allowed file types, matches
- // against either file type or file name:
- acceptFileTypes: /.+$/i,
- // The regular expression to define for which files a preview
- // image is shown, matched against the file type:
- previewSourceFileTypes: /^image\/(gif|jpeg|png)$/,
- // The maximum file size of images that are to be displayed as preview:
- previewSourceMaxFileSize: 5000000, // 5MB
- // The maximum width of the preview images:
- previewMaxWidth: 80,
- // The maximum height of the preview images:
- previewMaxHeight: 80,
- // By default, preview images are displayed as canvas elements
- // if supported by the browser. Set the following option to false
- // to always display preview images as img elements:
- previewAsCanvas: true,
// The ID of the upload template:
uploadTemplateId: 'template-upload',
// The ID of the download template:
downloadTemplateId: 'template-download',
// The container for the list of files. If undefined, it is set to
@@ -77,84 +67,117 @@
prependFiles: false,
// The expected data type of the upload response, sets the dataType
// option of the $.ajax upload requests:
dataType: 'json',
+ // Error and info messages:
+ messages: {
+ unknownError: 'Unknown error'
+ },
+
+ // Function returning the current number of files,
+ // used by the maxNumberOfFiles validation:
+ getNumberOfFiles: function () {
+ return this.filesContainer.children()
+ .not('.processing').length;
+ },
+
+ // Callback to retrieve the list of files from the server response:
+ getFilesFromResponse: function (data) {
+ if (data.result && $.isArray(data.result.files)) {
+ return data.result.files;
+ }
+ return [];
+ },
+
// The add callback is invoked as soon as files are added to the fileupload
// widget (via file input selection, drag & drop or add API call).
// See the basic file upload widget for more information:
add: function (e, data) {
- var that = $(this).data('blueimp-fileupload') ||
- $(this).data('fileupload'),
- options = that.options,
- files = data.files;
- $(this).fileupload('process', data).done(function () {
- that._adjustMaxNumberOfFiles(-files.length);
- data.maxNumberOfFilesAdjusted = true;
- data.files.valid = data.isValidated = that._validate(files);
- data.context = that._renderUpload(files).data('data', data);
- options.filesContainer[
- options.prependFiles ? 'prepend' : 'append'
- ](data.context);
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
+ var $this = $(this),
+ that = $this.data('blueimp-fileupload') ||
+ $this.data('fileupload'),
+ options = that.options;
+ data.context = that._renderUpload(data.files)
+ .data('data', data)
+ .addClass('processing');
+ options.filesContainer[
+ options.prependFiles ? 'prepend' : 'append'
+ ](data.context);
+ that._forceReflow(data.context);
+ that._transition(data.context);
+ data.process(function () {
+ return $this.fileupload('process', data);
+ }).always(function () {
+ data.context.each(function (index) {
+ $(this).find('.size').text(
+ that._formatFileSize(data.files[index].size)
+ );
+ }).removeClass('processing');
that._renderPreviews(data);
- that._forceReflow(data.context);
- that._transition(data.context).done(
- function () {
- if ((that._trigger('added', e, data) !== false) &&
- (options.autoUpload || data.autoUpload) &&
- data.autoUpload !== false && data.isValidated) {
- data.submit();
+ }).done(function () {
+ data.context.find('.start').prop('disabled', false);
+ if ((that._trigger('added', e, data) !== false) &&
+ (options.autoUpload || data.autoUpload) &&
+ data.autoUpload !== false) {
+ data.submit();
+ }
+ }).fail(function () {
+ if (data.files.error) {
+ data.context.each(function (index) {
+ var error = data.files[index].error;
+ if (error) {
+ $(this).find('.error').text(error);
}
- }
- );
+ });
+ }
});
},
// Callback for the start of each file upload request:
send: function (e, data) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload');
- if (!data.isValidated) {
- if (!data.maxNumberOfFilesAdjusted) {
- that._adjustMaxNumberOfFiles(-data.files.length);
- data.maxNumberOfFilesAdjusted = true;
- }
- if (!that._validate(data.files)) {
- return false;
- }
- }
if (data.context && data.dataType &&
data.dataType.substr(0, 6) === 'iframe') {
// Iframe Transport does not support progress events.
// In lack of an indeterminate progress bar, we set
// the progress to 100%, showing the full animated bar:
data.context
.find('.progress').addClass(
!$.support.transition && 'progress-animated'
)
.attr('aria-valuenow', 100)
- .find('.bar').css(
+ .children().first().css(
'width',
'100%'
);
}
return that._trigger('sent', e, data);
},
// Callback for successful uploads:
done: function (e, data) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload'),
- files = that._getFilesFromResponse(data),
+ getFilesFromResponse = data.getFilesFromResponse ||
+ that.options.getFilesFromResponse,
+ files = getFilesFromResponse(data),
template,
deferred;
if (data.context) {
data.context.each(function (index) {
var file = files[index] ||
- {error: 'Empty file upload result'},
- deferred = that._addFinishedDeferreds();
- if (file.error) {
- that._adjustMaxNumberOfFiles(1);
- }
+ {error: 'Empty file upload result'};
+ deferred = that._addFinishedDeferreds();
that._transition($(this)).done(
function () {
var node = $(this);
template = that._renderDownload([file])
.replaceAll(node);
@@ -169,23 +192,13 @@
);
}
);
});
} else {
- if (files.length) {
- $.each(files, function (index, file) {
- if (data.maxNumberOfFilesAdjusted && file.error) {
- that._adjustMaxNumberOfFiles(1);
- } else if (!data.maxNumberOfFilesAdjusted &&
- !file.error) {
- that._adjustMaxNumberOfFiles(-1);
- }
- });
- data.maxNumberOfFilesAdjusted = true;
- }
- template = that._renderDownload(files)
- .appendTo(that.options.filesContainer);
+ template = that._renderDownload(files)[
+ that.options.prependFiles ? 'prependTo' : 'appendTo'
+ ](that.options.filesContainer);
that._forceReflow(template);
deferred = that._addFinishedDeferreds();
that._transition(template).done(
function () {
data.context = $(this);
@@ -196,23 +209,23 @@
);
}
},
// Callback for failed (abort or error) uploads:
fail: function (e, data) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload'),
template,
deferred;
- if (data.maxNumberOfFilesAdjusted) {
- that._adjustMaxNumberOfFiles(data.files.length);
- }
if (data.context) {
data.context.each(function (index) {
if (data.errorThrown !== 'abort') {
var file = data.files[index];
file.error = file.error || data.errorThrown ||
- true;
+ data.i18n('unknownError');
deferred = that._addFinishedDeferreds();
that._transition($(this)).done(
function () {
var node = $(this);
template = that._renderDownload([file])
@@ -239,12 +252,13 @@
}
);
}
});
} else if (data.errorThrown !== 'abort') {
- data.context = that._renderUpload(data.files)
- .appendTo(that.options.filesContainer)
+ data.context = that._renderUpload(data.files)[
+ that.options.prependFiles ? 'prependTo' : 'appendTo'
+ ](that.options.filesContainer)
.data('data', data);
that._forceReflow(data.context);
deferred = that._addFinishedDeferreds();
that._transition(data.context).done(
function () {
@@ -260,22 +274,30 @@
that._addFinishedDeferreds().resolve();
}
},
// Callback for upload progress events:
progress: function (e, data) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
+ var progress = Math.floor(data.loaded / data.total * 100);
if (data.context) {
- var progress = Math.floor(data.loaded / data.total * 100);
- data.context.find('.progress')
- .attr('aria-valuenow', progress)
- .find('.bar').css(
- 'width',
- progress + '%'
- );
+ data.context.each(function () {
+ $(this).find('.progress')
+ .attr('aria-valuenow', progress)
+ .children().first().css(
+ 'width',
+ progress + '%'
+ );
+ });
}
},
// Callback for global upload progress events:
progressall: function (e, data) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var $this = $(this),
progress = Math.floor(data.loaded / data.total * 100),
globalProgressNode = $this.find('.fileupload-progress'),
extendedProgressNode = globalProgressNode
.find('.progress-extended');
@@ -286,17 +308,20 @@
);
}
globalProgressNode
.find('.progress')
.attr('aria-valuenow', progress)
- .find('.bar').css(
+ .children().first().css(
'width',
progress + '%'
);
},
// Callback for uploads start, equivalent to the global ajaxStart event:
start: function (e) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload');
that._resetFinishedDeferreds();
that._transition($(this).find('.fileupload-progress')).done(
function () {
@@ -304,10 +329,13 @@
}
);
},
// Callback for uploads stop, equivalent to the global ajaxStop event:
stop: function (e) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload'),
deferred = that._addFinishedDeferreds();
$.when.apply($, that._getFinishedDeferreds())
.done(function () {
@@ -315,30 +343,50 @@
});
that._transition($(this).find('.fileupload-progress')).done(
function () {
$(this).find('.progress')
.attr('aria-valuenow', '0')
- .find('.bar').css('width', '0%');
+ .children().first().css('width', '0%');
$(this).find('.progress-extended').html(' ');
deferred.resolve();
}
);
},
+ processstart: function (e) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
+ $(this).addClass('fileupload-processing');
+ },
+ processstop: function (e) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
+ $(this).removeClass('fileupload-processing');
+ },
// Callback for file deletion:
destroy: function (e, data) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var that = $(this).data('blueimp-fileupload') ||
- $(this).data('fileupload');
- if (data.url) {
- $.ajax(data).done(function () {
+ $(this).data('fileupload'),
+ removeNode = function () {
that._transition(data.context).done(
function () {
$(this).remove();
- that._adjustMaxNumberOfFiles(1);
that._trigger('destroyed', e, data);
}
);
+ };
+ if (data.url) {
+ data.dataType = data.dataType || that.options.dataType;
+ $.ajax(data).done(removeNode).fail(function () {
+ that._trigger('destroyfailed', e, data);
});
+ } else {
+ removeNode();
}
}
},
_resetFinishedDeferreds: function () {
@@ -355,17 +403,10 @@
_getFinishedDeferreds: function () {
return this._finishedUploads;
},
- _getFilesFromResponse: function (data) {
- if (data.result && $.isArray(data.result.files)) {
- return data.result.files;
- }
- return [];
- },
-
// Link handler, that allows to download files
// by drag & drop of the links to the desktop:
_enableDragToDesktop: function () {
var link = $(this),
url = link.prop('href'),
@@ -375,25 +416,14 @@
try {
e.originalEvent.dataTransfer.setData(
'DownloadURL',
[type, name, url].join(':')
);
- } catch (err) {}
+ } catch (ignore) {}
});
},
- _adjustMaxNumberOfFiles: function (operand) {
- if (typeof this.options.maxNumberOfFiles === 'number') {
- this.options.maxNumberOfFiles += operand;
- if (this.options.maxNumberOfFiles < 1) {
- this._disableFileInputButton();
- } else {
- this._enableFileInputButton();
- }
- }
- },
-
_formatFileSize: function (bytes) {
if (typeof bytes !== 'number') {
return '';
}
if (bytes >= 1000000000) {
@@ -445,50 +475,10 @@
) + ' | ' +
this._formatFileSize(data.loaded) + ' / ' +
this._formatFileSize(data.total);
},
- _hasError: function (file) {
- if (file.error) {
- return file.error;
- }
- // The number of added files is subtracted from
- // maxNumberOfFiles before validation, so we check if
- // maxNumberOfFiles is below 0 (instead of below 1):
- if (this.options.maxNumberOfFiles < 0) {
- return 'Maximum number of files exceeded';
- }
- // Files are accepted if either the file type or the file name
- // matches against the acceptFileTypes regular expression, as
- // only browsers with support for the File API report the type:
- if (!(this.options.acceptFileTypes.test(file.type) ||
- this.options.acceptFileTypes.test(file.name))) {
- return 'Filetype not allowed';
- }
- if (this.options.maxFileSize &&
- file.size > this.options.maxFileSize) {
- return 'File is too big';
- }
- if (typeof file.size === 'number' &&
- file.size < this.options.minFileSize) {
- return 'File is too small';
- }
- return null;
- },
-
- _validate: function (files) {
- var that = this,
- valid = !!files.length;
- $.each(files, function (index, file) {
- file.error = that._hasError(file);
- if (file.error) {
- valid = false;
- }
- });
- return valid;
- },
-
_renderTemplate: function (func, files) {
if (!func) {
return $();
}
var result = func({
@@ -500,67 +490,14 @@
return result;
}
return $(this.options.templatesContainer).html(result).children();
},
- _renderPreview: function (file, node) {
- var that = this,
- options = this.options,
- dfd = $.Deferred();
- return ((loadImage && loadImage(
- file,
- function (img) {
- node.append(img);
- that._forceReflow(node);
- that._transition(node).done(function () {
- dfd.resolveWith(node);
- });
- if (!$.contains(that.document[0].body, node[0])) {
- // If the element is not part of the DOM,
- // transition events are not triggered,
- // so we have to resolve manually:
- dfd.resolveWith(node);
- }
- node.on('remove', function () {
- // If the element is removed before the
- // transition finishes, transition events are
- // not triggered, resolve manually:
- dfd.resolveWith(node);
- });
- },
- {
- maxWidth: options.previewMaxWidth,
- maxHeight: options.previewMaxHeight,
- canvas: options.previewAsCanvas
- }
- )) || dfd.resolveWith(node)) && dfd;
- },
-
_renderPreviews: function (data) {
- var that = this,
- options = this.options;
- data.context.find('.preview span').each(function (index, element) {
- var file = data.files[index];
- if (options.previewSourceFileTypes.test(file.type) &&
- ($.type(options.previewSourceMaxFileSize) !== 'number' ||
- file.size < options.previewSourceMaxFileSize)) {
- that._processingQueue = that._processingQueue.pipe(function () {
- var dfd = $.Deferred(),
- ev = $.Event('previewdone', {
- target: element
- });
- that._renderPreview(file, $(element)).done(
- function () {
- that._trigger(ev.type, ev, data);
- dfd.resolveWith(that);
- }
- );
- return dfd.promise();
- });
- }
+ data.context.find('.preview').each(function (index, elm) {
+ $(elm).append(data.files[index].preview);
});
- return this._processingQueue;
},
_renderUpload: function (files) {
return this._renderTemplate(
this.options.uploadTemplate,
@@ -578,24 +515,27 @@
_startHandler: function (e) {
e.preventDefault();
var button = $(e.currentTarget),
template = button.closest('.template-upload'),
data = template.data('data');
- if (data && data.submit && !data.jqXHR && data.submit()) {
- button.prop('disabled', true);
+ button.prop('disabled', true);
+ if (data && data.submit) {
+ data.submit();
}
},
_cancelHandler: function (e) {
e.preventDefault();
- var template = $(e.currentTarget).closest('.template-upload'),
+ var template = $(e.currentTarget)
+ .closest('.template-upload,.template-download'),
data = template.data('data') || {};
- if (!data.jqXHR) {
+ data.context = data.context || template;
+ if (data.abort) {
+ data.abort();
+ } else {
data.errorThrown = 'abort';
this._trigger('fail', e, data);
- } else {
- data.jqXHR.abort();
}
},
_deleteHandler: function (e) {
e.preventDefault();
@@ -729,58 +669,21 @@
} else if (!(options.filesContainer instanceof $)) {
options.filesContainer = $(options.filesContainer);
}
},
- _stringToRegExp: function (str) {
- var parts = str.split('/'),
- modifiers = parts.pop();
- parts.shift();
- return new RegExp(parts.join('/'), modifiers);
- },
-
- _initRegExpOptions: function () {
- var options = this.options;
- if ($.type(options.acceptFileTypes) === 'string') {
- options.acceptFileTypes = this._stringToRegExp(
- options.acceptFileTypes
- );
- }
- if ($.type(options.previewSourceFileTypes) === 'string') {
- options.previewSourceFileTypes = this._stringToRegExp(
- options.previewSourceFileTypes
- );
- }
- },
-
_initSpecialOptions: function () {
this._super();
this._initFilesContainer();
this._initTemplates();
- this._initRegExpOptions();
},
- _setOption: function (key, value) {
- this._super(key, value);
- if (key === 'maxNumberOfFiles') {
- this._adjustMaxNumberOfFiles(0);
- }
- },
-
_create: function () {
this._super();
- this._refreshOptionsList.push(
- 'filesContainer',
- 'uploadTemplateId',
- 'downloadTemplateId'
- );
- if (!this._processingQueue) {
- this._processingQueue = $.Deferred().resolveWith(this).promise();
- this.process = function () {
- return this._processingQueue;
- };
- }
this._resetFinishedDeferreds();
+ if (!$.support.fileInput) {
+ this._disableFileInputButton();
+ }
},
enable: function () {
var wasDisabled = false;
if (this.options.disabled) {