Chamilo is a learning management system focused on ease of use and accessibility
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
chamilo-lms/main/inc/lib/javascript/jquery-upload/jquery.fileupload-ui.js

533 lines
20 KiB

/*
* jQuery File Upload User Interface Plugin 4.4.1
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://creativecommons.org/licenses/MIT/
*/
/*jslint browser: true, unparam: true */
/*global jQuery, FileReader, URL, webkitURL */
(function ($) {
'use strict';
var undef = 'undefined',
func = 'function',
UploadHandler,
methods,
MultiLoader = function (callBack) {
var loaded = 0,
list = [];
this.complete = function () {
loaded += 1;
if (loaded === list.length + 1) {
// list.length * onComplete + 1 * onLoadAll
callBack(list);
loaded = 0;
list = [];
}
};
this.push = function (item) {
list.push(item);
};
this.getList = function () {
return list;
};
};
UploadHandler = function (container, options) {
var uploadHandler = this,
dragOverTimeout,
isDropZoneEnlarged,
multiLoader = new MultiLoader(function (list) {
uploadHandler.hideProgressBarAll(function () {
uploadHandler.resetProgressBarAll();
if (typeof uploadHandler.onCompleteAll === func) {
uploadHandler.onCompleteAll(list);
}
});
}),
getUploadTable = function (handler) {
return typeof handler.uploadTable === func ?
handler.uploadTable(handler) : handler.uploadTable;
},
getDownloadTable = function (handler) {
return typeof handler.downloadTable === func ?
handler.downloadTable(handler) : handler.downloadTable;
};
this.requestHeaders = {'Accept': 'application/json, text/javascript, */*; q=0.01'};
this.dropZone = container;
this.imageTypes = /^image\/(gif|jpeg|png)$/;
this.previewMaxWidth = this.previewMaxHeight = 80;
this.previewLoadDelay = 100;
this.previewAsCanvas = true;
this.previewSelector = '.file_upload_preview';
this.progressSelector = '.file_upload_progress div';
this.cancelSelector = '.file_upload_cancel button';
this.cssClassSmall = 'file_upload_small';
this.cssClassLarge = 'file_upload_large';
this.cssClassHighlight = 'file_upload_highlight';
this.dropEffect = 'highlight';
this.uploadTable = this.downloadTable = null;
this.buildUploadRow = this.buildDownloadRow = null;
this.progressAllNode = null;
this.loadImage = function (file, callBack, maxWidth, maxHeight, imageTypes, noCanvas) {
var img,
scaleImage,
urlAPI,
fileReader;
if (imageTypes && !imageTypes.test(file.type)) {
return null;
}
scaleImage = function (img) {
var canvas = document.createElement('canvas'),
scale = Math.min(
(maxWidth || img.width) / img.width,
(maxHeight || img.height) / img.height
);
if (scale > 1) {
scale = 1;
}
img.width = parseInt(img.width * scale, 10);
img.height = parseInt(img.height * scale, 10);
if (noCanvas || typeof canvas.getContext !== func) {
return img;
}
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
return canvas;
};
img = document.createElement('img');
urlAPI = typeof URL !== undef ? URL : typeof webkitURL !== undef ? webkitURL : null;
if (urlAPI && typeof urlAPI.createObjectURL === func) {
img.onload = function () {
urlAPI.revokeObjectURL(this.src);
callBack(scaleImage(img));
};
img.src = urlAPI.createObjectURL(file);
} else if (typeof FileReader !== undef &&
typeof FileReader.prototype.readAsDataURL === func) {
img.onload = function () {
callBack(scaleImage(img));
};
fileReader = new FileReader();
fileReader.onload = function (e) {
img.src = e.target.result;
};
fileReader.readAsDataURL(file);
} else {
callBack(null);
}
};
this.addNode = function (parentNode, node, callBack) {
if (parentNode && parentNode.length && node && node.length) {
node.css('display', 'none').appendTo(parentNode).fadeIn(function () {
if (typeof callBack === func) {
try {
callBack();
} catch (e) {
// Fix endless exception loop:
node.stop();
throw e;
}
}
});
} else if (typeof callBack === func) {
callBack();
}
};
this.removeNode = function (node, callBack) {
if (node && node.length) {
node.fadeOut(function () {
node.remove();
if (typeof callBack === func) {
try {
callBack();
} catch (e) {
// Fix endless exception loop:
node.stop();
throw e;
}
}
});
} else if (typeof callBack === func) {
callBack();
}
};
this.replaceNode = function (oldNode, newNode, callBack) {
if (!(newNode && newNode.length)) {
return uploadHandler.removeNode(oldNode, callBack);
}
if (oldNode && oldNode.length) {
oldNode.fadeOut(function () {
newNode.css('display', 'none');
oldNode.replaceWith(newNode);
newNode.fadeIn(function () {
if (typeof callBack === func) {
try {
callBack();
} catch (e) {
// Fix endless exception loop:
oldNode.stop();
newNode.stop();
throw e;
}
}
});
});
} else if (typeof callBack === func) {
callBack();
}
};
this.resetProgressBarAll = function () {
if (uploadHandler.progressbarAll) {
uploadHandler.progressbarAll.progressbar(
'value',
0
);
}
};
this.hideProgressBarAll = function (callBack) {
if (uploadHandler.progressbarAll && !$(getUploadTable(uploadHandler))
.find(uploadHandler.progressSelector + ':visible:first').length) {
uploadHandler.progressbarAll.fadeOut(callBack);
} else if (typeof callBack === func) {
callBack();
}
};
this.onAbort = function (event, files, index, xhr, handler) {
handler.removeNode(handler.uploadRow, handler.hideProgressBarAll);
};
this.cancelUpload = function (event, files, index, xhr, handler) {
var readyState = xhr.readyState;
xhr.abort();
// If readyState is below 2, abort() has no effect:
if (typeof readyState !== 'number' || readyState < 2) {
handler.onAbort(event, files, index, xhr, handler);
}
};
this.initProgressBar = function (node, value) {
if (!node || !node.length) {
return null;
}
if (typeof node.progressbar === func) {
return node.progressbar({
value: value
});
} else {
node.addClass('progressbar')
.append($('<div/>').css('width', value + '%'))
.progressbar = function (key, value) {
return this.each(function () {
if (key === 'destroy') {
$(this).removeClass('progressbar').empty();
} else {
$(this).children().css('width', value + '%');
}
});
};
return node;
}
};
this.destroyProgressBar = function (node) {
if (!node || !node.length) {
return null;
}
return node.progressbar('destroy');
};
this.initUploadProgress = function (xhr, handler) {
if (!xhr.upload && handler.progressbar) {
handler.progressbar.progressbar(
'value',
100 // indeterminate progress displayed by a full animated progress bar
);
}
};
this.initUploadProgressAll = function () {
if (uploadHandler.progressbarAll && uploadHandler.progressbarAll.is(':hidden')) {
uploadHandler.progressbarAll.fadeIn();
}
};
this.onSend = function (event, files, index, xhr, handler) {
handler.initUploadProgress(xhr, handler);
};
this.onProgress = function (event, files, index, xhr, handler) {
if (handler.progressbar && event.lengthComputable) {
handler.progressbar.progressbar(
'value',
parseInt(event.loaded / event.total * 100, 10)
);
}
};
this.onProgressAll = function (event, list) {
if (uploadHandler.progressbarAll && event.lengthComputable) {
uploadHandler.progressbarAll.progressbar(
'value',
parseInt(event.loaded / event.total * 100, 10)
);
}
};
this.onLoadAll = function (list) {
multiLoader.complete();
};
this.initProgressBarAll = function () {
if (!uploadHandler.progressbarAll) {
uploadHandler.progressbarAll = uploadHandler.initProgressBar(
(typeof uploadHandler.progressAllNode === func ?
uploadHandler.progressAllNode(uploadHandler) : uploadHandler.progressAllNode),
0
);
}
};
this.destroyProgressBarAll = function () {
uploadHandler.destroyProgressBar(uploadHandler.progressbarAll);
};
this.loadPreviewImage = function (files, index, handler) {
index = index || 0;
handler.uploadRow.find(handler.previewSelector).each(function () {
var previewNode = $(this),
file = files[index];
setTimeout(function () {
handler.loadImage(
file,
function (img) {
handler.addNode(
previewNode,
$(img)
);
},
handler.previewMaxWidth,
handler.previewMaxHeight,
handler.imageTypes,
!handler.previewAsCanvas
);
}, handler.previewLoadDelay);
index += 1;
});
};
this.initUploadRow = function (event, files, index, xhr, handler) {
var uploadRow = handler.uploadRow = (typeof handler.buildUploadRow === func ?
handler.buildUploadRow(files, index, handler) : null);
if (uploadRow) {
handler.progressbar = handler.initProgressBar(
uploadRow.find(handler.progressSelector),
0
);
uploadRow.find(handler.cancelSelector).click(function (e) {
handler.cancelUpload(e, files, index, xhr, handler);
e.preventDefault();
});
handler.loadPreviewImage(files, index, handler);
}
};
this.initUpload = function (event, files, index, xhr, handler, callBack) {
handler.initUploadRow(event, files, index, xhr, handler);
handler.addNode(
getUploadTable(handler),
handler.uploadRow,
function () {
if (typeof handler.beforeSend === func) {
handler.beforeSend(event, files, index, xhr, handler, callBack);
} else {
callBack();
}
}
);
handler.initUploadProgressAll();
};
this.parseResponse = function (xhr, handler) {
if (typeof xhr.responseText !== undef) {
return $.parseJSON(xhr.responseText);
} else {
// Instead of an XHR object, an iframe is used for legacy browsers:
return $.parseJSON(xhr.contents().text());
}
};
this.initDownloadRow = function (event, files, index, xhr, handler) {
var json, downloadRow;
try {
json = handler.response = handler.parseResponse(xhr, handler);
} catch (e) {
if (typeof handler.onError === func) {
handler.originalEvent = event;
handler.onError(e, files, index, xhr, handler);
} else {
throw e;
}
}
downloadRow = handler.downloadRow = (typeof handler.buildDownloadRow === func ?
handler.buildDownloadRow(json, handler) : null);
};
this.onLoad = function (event, files, index, xhr, handler) {
var uploadTable = getUploadTable(handler),
downloadTable = getDownloadTable(handler),
callBack = function () {
if (typeof handler.onComplete === func) {
handler.onComplete(event, files, index, xhr, handler);
}
multiLoader.complete();
};
multiLoader.push(Array.prototype.slice.call(arguments, 1));
handler.initDownloadRow(event, files, index, xhr, handler);
if (uploadTable && handler.uploadRow && handler.uploadRow.length &&
(!downloadTable || uploadTable.get(0) === downloadTable.get(0))) {
handler.replaceNode(handler.uploadRow, handler.downloadRow, callBack);
} else {
handler.removeNode(handler.uploadRow, function () {
handler.addNode(
downloadTable,
handler.downloadRow,
callBack
);
});
}
};
this.dropZoneEnlarge = function () {
if (!isDropZoneEnlarged) {
if (typeof uploadHandler.dropZone.switchClass === func) {
uploadHandler.dropZone.switchClass(
uploadHandler.cssClassSmall,
uploadHandler.cssClassLarge
);
} else {
uploadHandler.dropZone.addClass(uploadHandler.cssClassLarge);
uploadHandler.dropZone.removeClass(uploadHandler.cssClassSmall);
}
isDropZoneEnlarged = true;
}
};
this.dropZoneReduce = function () {
if (typeof uploadHandler.dropZone.switchClass === func) {
uploadHandler.dropZone.switchClass(
uploadHandler.cssClassLarge,
uploadHandler.cssClassSmall
);
} else {
uploadHandler.dropZone.addClass(uploadHandler.cssClassSmall);
uploadHandler.dropZone.removeClass(uploadHandler.cssClassLarge);
}
isDropZoneEnlarged = false;
};
this.onDocumentDragEnter = function (event) {
uploadHandler.dropZoneEnlarge();
};
this.onDocumentDragOver = function (event) {
if (dragOverTimeout) {
clearTimeout(dragOverTimeout);
}
dragOverTimeout = setTimeout(function () {
uploadHandler.dropZoneReduce();
}, 200);
};
this.onDragEnter = this.onDragLeave = function (event) {
uploadHandler.dropZone.toggleClass(uploadHandler.cssClassHighlight);
};
this.onDrop = function (event) {
if (dragOverTimeout) {
clearTimeout(dragOverTimeout);
}
if (uploadHandler.dropEffect && typeof uploadHandler.dropZone.effect === func) {
uploadHandler.dropZone.effect(uploadHandler.dropEffect, function () {
uploadHandler.dropZone.removeClass(uploadHandler.cssClassHighlight);
uploadHandler.dropZoneReduce();
});
} else {
uploadHandler.dropZone.removeClass(uploadHandler.cssClassHighlight);
uploadHandler.dropZoneReduce();
}
};
this.init = function () {
uploadHandler.initProgressBarAll();
if (typeof uploadHandler.initExtended === func) {
uploadHandler.initExtended();
}
};
this.destroy = function () {
if (typeof uploadHandler.destroyExtended === func) {
uploadHandler.destroyExtended();
}
uploadHandler.destroyProgressBarAll();
};
$.extend(this, options);
};
methods = {
init : function (options) {
return this.each(function () {
$(this).fileUpload(new UploadHandler($(this), options));
});
},
option: function (option, value, namespace) {
if (!option || (typeof option === 'string' && typeof value === undef)) {
return $(this).fileUpload('option', option, value, namespace);
}
return this.each(function () {
$(this).fileUpload('option', option, value, namespace);
});
},
destroy : function (namespace) {
return this.each(function () {
$(this).fileUpload('destroy', namespace);
});
},
upload: function (files, namespace) {
return this.each(function () {
$(this).fileUpload('upload', files, namespace);
});
}
};
$.fn.fileUploadUI = function (method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method "' + method + '" does not exist on jQuery.fileUploadUI');
}
};
}(jQuery));