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.
308 lines
11 KiB
308 lines
11 KiB
/*
|
|
* jQuery File Upload User Interface Plugin 3.6
|
|
*
|
|
* Copyright 2010, Sebastian Tschan, AQUANTUM
|
|
* Licensed under the MIT license:
|
|
* http://creativecommons.org/licenses/MIT/
|
|
*
|
|
* https://blueimp.net
|
|
* http://www.aquantum.de
|
|
*/
|
|
|
|
/*jslint browser: true */
|
|
/*global jQuery, FileReader, URL */
|
|
|
|
(function ($) {
|
|
|
|
var undef = 'undefined',
|
|
func = 'function',
|
|
UploadHandler,
|
|
methods,
|
|
|
|
LocalImage = function (file, imageTypes) {
|
|
var img,
|
|
fileReader;
|
|
if (!imageTypes.test(file.type)) {
|
|
return null;
|
|
}
|
|
img = document.createElement('img');
|
|
if (typeof URL !== undef && typeof URL.createObjectURL === func) {
|
|
img.src = URL.createObjectURL(file);
|
|
img.onload = function () {
|
|
URL.revokeObjectURL(this.src);
|
|
};
|
|
return img;
|
|
}
|
|
if (typeof FileReader !== undef) {
|
|
fileReader = new FileReader();
|
|
if (typeof fileReader.readAsDataURL === func) {
|
|
fileReader.onload = function (e) {
|
|
img.src = e.target.result;
|
|
};
|
|
fileReader.readAsDataURL(file);
|
|
return img;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
UploadHandler = function (container, options) {
|
|
var uploadHandler = this,
|
|
dragOverTimeout,
|
|
isDropZoneEnlarged;
|
|
|
|
this.dropZone = container;
|
|
this.imageTypes = /^image\/(gif|jpeg|png)$/;
|
|
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 = function () {
|
|
return null;
|
|
};
|
|
|
|
this.addNode = function (parentNode, node, callBack) {
|
|
if (node) {
|
|
node.css('display', 'none').appendTo(parentNode).fadeIn(function () {
|
|
if (typeof callBack === func) {
|
|
try {
|
|
callBack();
|
|
} catch (e) {
|
|
// Fix endless exception loop:
|
|
$(this).stop();
|
|
throw e;
|
|
}
|
|
}
|
|
});
|
|
} else if (typeof callBack === func) {
|
|
callBack();
|
|
}
|
|
};
|
|
|
|
this.removeNode = function (node, callBack) {
|
|
if (node) {
|
|
node.fadeOut(function () {
|
|
$(this).remove();
|
|
if (typeof callBack === func) {
|
|
try {
|
|
callBack();
|
|
} catch (e) {
|
|
// Fix endless exception loop:
|
|
$(this).stop();
|
|
throw e;
|
|
}
|
|
}
|
|
});
|
|
} else if (typeof callBack === func) {
|
|
callBack();
|
|
}
|
|
};
|
|
|
|
this.onAbort = function (event, files, index, xhr, handler) {
|
|
handler.removeNode(handler.uploadRow);
|
|
};
|
|
|
|
this.cancelUpload = function (event, files, index, xhr, handler) {
|
|
var readyState = xhr.readyState;
|
|
xhr.abort();
|
|
// If readyState is below 2, abort() has no effect:
|
|
if (isNaN(readyState) || readyState < 2) {
|
|
handler.onAbort(event, files, index, xhr, handler);
|
|
}
|
|
};
|
|
|
|
this.initProgressBar = function (node, value) {
|
|
if (typeof node.progressbar === func) {
|
|
return node.progressbar({
|
|
value: value
|
|
});
|
|
} else {
|
|
var progressbar = $('<progress value="' + value + '" max="100"/>').appendTo(node);
|
|
progressbar.progressbar = function (key, value) {
|
|
progressbar.attr('value', value);
|
|
};
|
|
return progressbar;
|
|
}
|
|
};
|
|
|
|
this.initUploadRow = function (event, files, index, xhr, handler, callBack) {
|
|
var uploadRow = handler.uploadRow = handler.buildUploadRow(files, index, handler);
|
|
if (uploadRow) {
|
|
handler.progressbar = handler.initProgressBar(
|
|
uploadRow.find(handler.progressSelector),
|
|
(xhr.upload ? 0 : 100)
|
|
);
|
|
uploadRow.find(handler.cancelSelector).click(function (e) {
|
|
handler.cancelUpload(e, files, index, xhr, handler);
|
|
});
|
|
uploadRow.find(handler.previewSelector).each(function () {
|
|
$(this).append(new LocalImage(files[index], handler.imageTypes));
|
|
});
|
|
}
|
|
handler.addNode(
|
|
(typeof handler.uploadTable === func ? handler.uploadTable(handler) : handler.uploadTable),
|
|
uploadRow,
|
|
callBack
|
|
);
|
|
};
|
|
|
|
this.initUpload = function (event, files, index, xhr, handler, callBack) {
|
|
handler.initUploadRow(event, files, index, xhr, handler, function () {
|
|
if (typeof handler.beforeSend === func) {
|
|
handler.beforeSend(event, files, index, xhr, handler, callBack);
|
|
} else {
|
|
callBack();
|
|
}
|
|
});
|
|
};
|
|
|
|
this.onProgress = function (event, files, index, xhr, handler) {
|
|
if (handler.progressbar) {
|
|
handler.progressbar.progressbar(
|
|
'value',
|
|
parseInt(event.loaded / event.total * 100, 10)
|
|
);
|
|
}
|
|
};
|
|
|
|
this.parseResponse = function (xhr) {
|
|
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, callBack) {
|
|
var json, downloadRow;
|
|
try {
|
|
json = handler.response = handler.parseResponse(xhr);
|
|
downloadRow = handler.downloadRow = handler.buildDownloadRow(json, handler);
|
|
handler.addNode(
|
|
(typeof handler.downloadTable === func ? handler.downloadTable(handler) : handler.downloadTable),
|
|
downloadRow,
|
|
callBack
|
|
);
|
|
} catch (e) {
|
|
if (typeof handler.onError === func) {
|
|
handler.originalEvent = event;
|
|
handler.onError(e, files, index, xhr, handler);
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
};
|
|
|
|
this.onLoad = function (event, files, index, xhr, handler) {
|
|
handler.removeNode(handler.uploadRow, function () {
|
|
handler.initDownloadRow(event, files, index, xhr, handler, function () {
|
|
if (typeof handler.onComplete === func) {
|
|
handler.onComplete(event, files, index, xhr, handler);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
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();
|
|
}
|
|
};
|
|
|
|
$.extend(this, options);
|
|
};
|
|
|
|
methods = {
|
|
init : function (options) {
|
|
return this.each(function () {
|
|
$(this).fileUpload(new UploadHandler($(this), options));
|
|
});
|
|
},
|
|
|
|
option: function (option, value, namespace) {
|
|
if (typeof option === undef || (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);
|
|
});
|
|
}
|
|
};
|
|
|
|
$.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)); |