/*
* jQuery File Upload File Processing Plugin 1.0
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2012, 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, document */
(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define([
'jquery',
'load-image',
'canvas-to-blob',
'./jquery.fileupload'
], factory);
} else {
// Browser globals:
factory(
window.jQuery,
window.loadImage
);
}
}(function ($, loadImage) {
'use strict';
// The File Upload IP version extends the basic fileupload widget
// with file processing functionality:
$.widget('blueimpFP.image_upload_form', $.blueimp.image_upload_form, {
options: {
// The list of file processing actions:
process: [
/*
{
action: 'load',
fileTypes: /^image\/(gif|jpeg|png)$/,
maxFileSize: 20000000 // 20MB
},
{
action: 'resize',
maxWidth: 1920,
maxHeight: 1200,
minWidth: 800,
minHeight: 600
},
{
action: 'save'
}
*/
],
// 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) {
$(this).image_upload_form('process', data).done(function () {
data.submit();
});
}
},
processActions: {
// Loads the image given via data.files and data.index
// as canvas element.
// Accepts the options fileTypes (regular expression)
// and maxFileSize (integer) to limit the files to load:
load: function (data, options) {
var that = this,
file = data.files[data.index],
dfd = $.Deferred();
if (window.HTMLCanvasElement &&
window.HTMLCanvasElement.prototype.toBlob &&
($.type(options.maxFileSize) !== 'number' ||
file.size < options.maxFileSize) &&
(!options.fileTypes ||
options.fileTypes.test(file.type))) {
loadImage(
file,
function (canvas) {
data.canvas = canvas;
dfd.resolveWith(that, [data]);
},
{canvas: true}
);
} else {
dfd.rejectWith(that, [data]);
}
return dfd.promise();
},
// Resizes the image given as data.canvas and updates
// data.canvas with the resized image.
// Accepts the options maxWidth, maxHeight, minWidth and
// minHeight to scale the given image:
resize: function (data, options) {
if (data.canvas) {
var canvas = loadImage.scale(data.canvas, options);
if (canvas.width !== data.canvas.width ||
canvas.height !== data.canvas.height) {
data.canvas = canvas;
data.processed = true;
}
}
return data;
},
// Saves the processed image given as data.canvas
// inplace at data.index of data.files:
save: function (data, options) {
// Do nothing if no processing has happened:
if (!data.canvas || !data.processed) {
return data;
}
var that = this,
file = data.files[data.index],
name = file.name,
dfd = $.Deferred(),
callback = function (blob) {
if (!blob.name) {
if (file.type === blob.type) {
blob.name = file.name;
} else if (file.name) {
blob.name = file.name.replace(
/\..+$/,
'.' + blob.type.substr(6)
);
}
}
// Store the created blob at the position
// of the original file in the files list:
data.files[data.index] = blob;
dfd.resolveWith(that, [data]);
};
// Use canvas.mozGetAsFile directly, to retain the filename, as
// Gecko doesn't support the filename option for FormData.append:
if (data.canvas.mozGetAsFile) {
callback(data.canvas.mozGetAsFile(
(/^image\/(jpeg|png)$/.test(file.type) && name) ||
((name && name.replace(/\..+$/, '')) ||
'blob') + '.png',
file.type
));
} else {
data.canvas.toBlob(callback, file.type);
}
return dfd.promise();
}
},
// Resizes the file at the given index and stores the created blob at
// the original position of the files list, returns a Promise object:
_processFile: function (files, index, options) {
var that = this,
dfd = $.Deferred().resolveWith(that, [{
files: files,
index: index
}]),
chain = dfd.promise();
that._processing += 1;
$.each(options.process, function (i, settings) {
chain = chain.pipe(function (data) {
return that.processActions[settings.action]
.call(this, data, settings);
});
});
chain.always(function () {
that._processing -= 1;
if (that._processing === 0) {
that.element
.removeClass('fileupload-processing');
}
});
if (that._processing === 1) {
that.element.addClass('fileupload-processing');
}
return chain;
},
// Processes the files given as files property of the data parameter,
// returns a Promise object that allows to bind a done handler, which
// will be invoked after processing all files (inplace) is done:
process: function (data) {
var that = this,
options = $.extend({}, this.options, data);
if (options.process && options.process.length &&
this._isXHRUpload(options)) {
$.each(data.files, function (index, file) {
that._processingQueue = that._processingQueue.pipe(
function () {
var dfd = $.Deferred();
that._processFile(data.files, index, options)
.always(function () {
dfd.resolveWith(that);
});
return dfd.promise();
}
);
});
}
return this._processingQueue;
},
_create: function () {
$.blueimp.image_upload_form.prototype._create.call(this);
this._processing = 0;
this._processingQueue = $.Deferred().resolveWith(this)
.promise();
}
});
}));
|