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.

630 lines
19 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* HTML5上传插件
* @site https://git.oschina.net/blackfox/ajaxUpload
* @author yangjian<yangjian102621@gmail.com>
* @version 1.0.1
*/
(function($) {
//判断浏览器是否支持html5
if ( typeof FormData == "undefined" )
throw new Error("您当前的浏览器不支持HTML5,请先升级浏览器才能使用该上传插件!");
//image crop
$.fn.imageCrop = function(__width, __height) {
$(this).on("load", function () {
var width, height, left, top;
var orgRate = this.width/this.height;
var cropRate = __width/__height;
if ( orgRate >= cropRate ) {
height = __height;
width = __width * orgRate;
top = 0;
left = (width - __width)/2;
} else {
width = __width;
height = __height / orgRate;
left = 0;
//top = (height - __height)/2;
top = 0;
}
$(this).css({
"position" : "absolute",
top : -top + "px",
left : -left + "px",
width : width + "px",
height : height + "px"
});
});
}
//make element draggable
$.fn.draggable = function(options) {
var defaults = {
handler : null
}
options = $.extend(defaults, options);
var __self = this;
$(options.handler).mousedown(function(e) {
var offsetLeft = e.pageX - $(__self).position().left;
var offsetTop = e.pageY - $(__self).position().top;
$(document).mousemove(function(e) {
//清除拖动鼠标的时候选择文本
window.getSelection ? window.getSelection().removeAllRanges():document.selection.empty();
$(__self).css({
'top' : e.pageY-offsetTop + 'px',
'left' : e.pageX-offsetLeft + 'px'
});
});
}).mouseup(function() {
$(document).unbind('mousemove');
});
}
if ( Array.prototype.remove == undefined ) {
Array.prototype.remove = function(item) {
for ( var i = 0; i < this.length; i++ ) {
if ( this[i] == item ) {
this.splice(i, 1);
break;
}
}
}
}
if ( Array.prototype.uinque == undefined ) {
Array.prototype.uinque = function() {
var result = [], hash = {};
for ( var i = 0, item; (item = this[i]) != null; i++ ) {
if ( !hash[item] ) {
result.push(item);
hash[item] = true;
}
}
return result;
}
}
window.BUpload = function(options) {
options = $.extend({
src : "src",
upload_url : null,
list_url : null,
data_type : "json",
top : 20,
fileType : "image", //文件类型默认是图片可选flash,media,file
max_filesize : 2048, //unit:KB
max_filenum : 20,
no_data_text : "(⊙o⊙)亲,没有多数据了。",
ext_allow : "jpg|png|gif|jpeg",
ext_refuse : "exe|txt",
extra_params : {},
errorHandler : function(messsage, type) {
alert(messsage);
},
callback : function(data) {
console.log(data);
}
}, options);
//错误代码和提示消息
var codeMessageMap = {
'000' : '文件上传成功',
'001' : '文件上传失败',
'003' : '文件大小超出限制',
'004' : '非法文件名后缀'
};
var mimeType = {
"3gpp":"audio/3gpp, video/3gpp",
"ac3":"audio/ac3",
"asf":"allpication/vnd.ms-asf",
"au":"audio/basic",
"css":"text/css",
"csv":"text/csv",
"doc":"application/msword",
"dot":"application/msword",
"dtd":"application/xml-dtd",
"dwg":"image/vnd.dwg",
"dxf":"image/vnd.dxf",
"gif":"image/gif",
"htm":"text/html",
"html":"text/html",
"jp2":"image/jp2",
"jpe":"image/jpeg",
"jpeg":"image/jpeg",
"jpg":"image/jpeg",
"js":"text/javascript, application/javascript",
"json":"application/json",
"mp2":"audio/mpeg, video/mpeg",
"mp3":"audio/mpeg",
"mp4":"audio/mp4, video/mp4",
"mpeg":"video/mpeg",
"mpg":"video/mpeg",
"mpp":"application/vnd.ms-project",
"ogg":"application/ogg, audio/ogg",
"pdf":"application/pdf",
"png":"image/png",
"pot":"application/vnd.ms-powerpoint",
"pps":"application/vnd.ms-powerpoint",
"ppt":"application/vnd.ms-powerpoint",
"rtf":"application/rtf, text/rtf",
"svf":"image/vnd.svf",
"tif":"image/tiff",
"tiff":"image/tiff",
"txt":"text/plain",
"wdb":"application/vnd.ms-works",
"wps":"application/vnd.ms-works",
"xhtml":"application/xhtml+xml",
"xlc":"application/vnd.ms-excel",
"xlm":"application/vnd.ms-excel",
"xls":"application/vnd.ms-excel",
"xlt":"application/vnd.ms-excel",
"xlw":"application/vnd.ms-excel",
"xml":"text/xml, application/xml",
"zip":"aplication/zip",
"xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
}
var o = {};
o.dialog = null;
o.todoList = new Array(); //the file queue to be uploaded
o.uploadSuccessNum = 0; //已经上传成功的图片数量
o.selectedList = new Array(); //the file queue upload successfully
o.addedFileNumber = 0; //the numbers of files that has added
o.totalFilesize = 0; //total file size
o.uploadLock = false; //upload thread lock
o.page = 1; //服务器图片列表页码
o.marker = null, //七牛云上传的分页标识
o.noRecord = false;
var dialogSCode = Math.ceil(Math.random() * 1000000000000); //对话框的令牌如果创建多个BUpload上传对象用来保持唯一性
//close the dialog
o.close = function () {
o.dialog.remove();
if (typeof options.close == 'function') {
options.close();
}
}
//create dialog
function createDialog() {
var builder = new StringBuilder();
builder.append('<div class="uedbody ke-animated"><div class="ued_title">');
builder.append('<div class="uedbar"><span>'+options.lang.title+'</span></div><div class="close_btn icon"' +
' title="'+options.lang.closeText+'"></div>');
builder.append('</div><div class="wrapper"><div id="wra_head" class="wra_head"><span class="tab' +
' tab-upload focus" tab="upload-panel">'+options.lang.localUpload+'</span>');
if ( options.list_url != null ) {
builder.append('<span class="tab tab-online" tab="online">'+options.lang.fileServer+'</span>');
}
builder.append('</div><div class="wra_body"><div class="tab-panel upload-panel"><div class="wra_pla"><div class="upload-image-placeholder">');
builder.append('<div class="btn btn-primary image-select">'+options.lang.selectFile+'</div><input type="file" name="'+options.src+'" class="webuploader-element-invisible"' +
' multiple="multiple" accept="'+getAccept()+'">');
builder.append('</div></div><div class="image-list-box" style="display: none;"><div class="wra_bar"><div class="info fl"></div>');
builder.append('<div class="fr"><span class="btn btn-default btn-continue-add">'+options.lang.continueAdd+'</span><span class="btn btn-primary btn-start-upload">'+options.lang.startUpload+'</span></div></div>');
builder.append('<ul class="filelist"></ul></div></div><div class="tab-panel online"><div class="imagelist"><ul class="list clearfix"></ul><div class="no-data"></div></div></div>');
builder.append('<div class="tab-panel searchbox"><div class="search-bar"><input class="searTxt"' +
' type="text" placeholder="'+options.lang.searchPlaceholder+'" />');
builder.append('<input value="'+options.lang.searchBtn+'" class="btn btn-primary btn-search" type="button" /><input value="'+options.lang.searchClear+'" class="btn btn-default btn-reset" type="button" />');
builder.append('</div><div class="search-imagelist-box"><ul class="search-list"></ul><div class="no-data"></div></div>');
builder.append('</div><div class="loading-icon"></div></div><!-- end of wrapper --></div><div class="wra-btn-group"><span class="btn btn-primary btn-confirm">'+options.lang.confirmBtnText+'</span>');
builder.append('<span class="btn btn-default btn-cancel">'+options.lang.cancelBtnText+'</span></div></div>');
o.dialog = $(builder.toString());
$("body").append(o.dialog);
if (options.top == 0) {
options.top = ($(window).height() - o.dialog.height())/2;
}
o.dialog.css({
left : ($(window).width() - o.dialog.width())/2 + "px",
top : options.top + "px"
});
//给对话框添加拖拽事件
o.dialog.draggable({handler : o.dialog.find(".ued_title")})
}
//绑定元素事件
function bindEvent() {
//选项卡事件
G(".tab").on("click", function() {
var tab = $(this).attr("tab");
G(".tab-panel").hide();
G("."+tab).show();
G(".tab").removeClass("focus");
$(this).addClass("focus");
});
//关闭对话框
G(".close_btn").on("click", function() {
o.close();
});
//选择文件事件
G(".webuploader-element-invisible").on("change", function() {
addFiles(this);
});
//弹出上传文件选择框
G(".image-select").on("click", function() {
G(".webuploader-element-invisible").trigger("click");
});
G(".btn-continue-add").on("click", function() {
G(".webuploader-element-invisible").trigger("click");
});
//开始上传按钮事件
G(".btn-start-upload").on("click", function() {
if ( o.uploadLock ) return;
if ( o.todoList.length == 0 ) {
options.errorHandler(options.lang.noFileAdded, "error");
return false;
}
$(this).addClass("disabled").text(options.lang.uploading);
uploadFile(o.todoList.shift());
});
//点击确认|取消按钮事件
G(".btn-confirm").on("click", function() {
if ( o.todoList.length > 0 ) {
options.errorHandler(options.lang.fileNotUpload, "error");
return false;
}
if (o.selectedList.length == 0) {
options.errorHandler(options.lang.noFileSelected, "error");
return false;
}
options.callback(o.selectedList);
o.close();
});
G(".btn-cancel").on("click", function() {
o.close();
});
//从服务器加载文件
G(".tab-online").on("click", function() {
if ( G(".imagelist .list").children().length == 0 ) {
loadFilesFromServer()
}
});
//当滚动条滚到底部时自动去加载图片
G(".imagelist").on("scroll", function() {
if ( this.scrollTop + this.clientHeight >= this.scrollHeight ) {
loadFilesFromServer();
}
});
}
//add file to upload list
function addFiles(input) {
var files = input.files;
var totalFileNum = o.todoList.length + o.uploadSuccessNum + files.length; //本次上传文件总数
for ( var i = o.addedFileNumber; i < o.addedFileNumber+files.length; i++ ) {
if ( totalFileNum > options.max_filenum ) {
options.errorHandler(KindEditor.tmpl(options.lang.uploadLimit, {uploadLimit: options.max_filenum}), "error");
return;
}
var builder = new StringBuilder();
var tempFile = files[i- o.addedFileNumber];
builder.append('<li id="img-comtainer-'+dialogSCode+i+'"><div class="imgWrap">');
//如果上传的不是图片,则通过判断文件后缀来显示不同的图标
var extension = getFileExt(tempFile.name);
if ( extension == '' ) extension = "default";
extension = extension.toLowerCase();
if ( "jpg|jpeg|gif|png|bmp".indexOf(extension) == -1 ) {
builder.append('<span class="icon-placeholder icon-default icon-'+extension+'"></span>');
} else {
builder.append('<img src="'+window.URL.createObjectURL(tempFile)+'" border="0" />');
}
builder.append('</div><div class="file-opt-box clearfix"><span class="remove" index="'+i+'">'+options.lang.remove+'</span><span class="rotateRight">'+options.lang.rotateRight+'</span>');
builder.append('<span class="rotateLeft">'+options.lang.rotateLeft+'</span></div><div class="success"></div><div class="error"></div>');
builder.append('<div class="progress"><span style="display: none; width: 0px;"></span></div></li>');
var $image = $(builder.toString());
//bind onelele event
$image.find(".remove").on("click", function() {
$(this).parents("li").remove(); //remove element
//remove file from todoList
var index = $(this).attr("index");
for ( var i = 0; i < o.todoList.length; i++ ) {
if ( o.todoList[i].index == index ) {
o.totalFilesize -= o.todoList[i].file.size;
updateInfoText(o.uploadSuccessNum + o.todoList.length-1, o.totalFilesize);
o.todoList.splice(i, 1);
break;
}
}
if (G(".filelist li").length == 0) {
G(".image-list-box").hide();
G(".wra_pla").show();
}
});
$image.on("mouseover", function() {
$(this).find(".file-opt-box").show();
}).on("mouseout", function() {
$(this).find(".file-opt-box").hide();
});
G(".wra_pla").hide();
G(".image-list-box").show();
G(".filelist").append($image);
o.todoList.push({index:i, file:tempFile});
o.totalFilesize += tempFile.size;
//console.log(tempFile);
}
o.addedFileNumber += files.length;
updateInfoText(o.uploadSuccessNum + o.todoList.length, o.totalFilesize);
//缩放并裁剪图片
$(".imgWrap img").imageCrop(113,113);
}
/**
* upload file function(文件上传主函数)
* @param node 数据节点
*/
function uploadFile(node) {
if ( !fileCheckHandler(node) ) {
uploadNextFile(); //skip the file and upload the next file
return;
}
// prepare XMLHttpRequest
var xhr = new XMLHttpRequest();
xhr.open('POST', options.upload_url);
//upload successfully
xhr.addEventListener('load',function(e) {
if ( options.data_type == "json" ) {
//console.log(e);
var data = $.parseJSON(e.target.responseText);
if ( data.code == "000" ) {
o.selectedList.push(data.data.url); //添加文件到上传文件列表
o.uploadSuccessNum++;
$("#img-comtainer-"+dialogSCode+ node.index).find(".file-opt-box").remove();
$("#img-comtainer-"+dialogSCode+ node.index).find(".progress").remove();
$("#img-comtainer-"+dialogSCode+ node.index).find(".success").show();
} else {
__error__(codeMessageMap[data.code], node);
}
}
}, false);
// file upload complete
xhr.addEventListener('loadend', function () {
uploadNextFile(); //upload the next file
}, false);
//上传失败
xhr.addEventListener('error', function() {
__error__(options.lang.uploadFail, node);
}, false);
xhr.upload.addEventListener('progress', function(e) {
updateProgress(e, node);
}, false);
// prepare FormData
var formData = new FormData();
formData.append(options.src, node.file);
// add extra params
for(var k in options.extra_params) {
formData.append(k, options.extra_params[k]);
}
xhr.send(formData);
}
//upload next file(上传下一个文件)
function uploadNextFile() {
if ( o.todoList.length ) {
var nextFile = o.todoList.shift();
uploadFile(nextFile);
} else {
o.uploadLock = false; //release the upload lock
G(".btn-start-upload").removeClass("disabled").text(options.lang.startUpload);
//console.log(o.selectedList);
}
}
// progress handler(文件上传进度控制)
function updateProgress(e, node) {
if ( e.lengthComputable ) {
$("#img-comtainer-"+dialogSCode+ node.index).find(".progress span").css({"width" : (e.loaded/e.total)*100+'%', "display":"block"});
}
}
//update file info text
function updateInfoText(filenum, filesize) {
var text = KindEditor.tmpl(options.lang.uploadDesc, {numSelect:filenum, totalSize:formatFileSize(filesize), numLeft:(options.max_filenum - filenum)});
G(".info").text(text);
}
//format file size(格式化文件大小)
function formatFileSize(size) {
if ( size/1048576 > 1 ) {
return (size/1048576).toFixed(2)+"MB";
} else {
return (size/1024).toFixed(2)+"KB";
}
}
//file check handler(文件检测处理函数)
function fileCheckHandler(node) {
//检查文件大小
var maxsize = options.max_filesize * 1024;
if ( maxsize > 0 && node.file.size > maxsize ) {
__error__(KindEditor.tmpl(options.lang.sizeLimit, {sizeLimit:options.max_filesize}), node);
return false;
}
//检查文件后缀名
var ext = getFileExt(node.file.name);
if ( ext && options.ext_allow.indexOf(ext) != -1
&& options.ext_refuse.indexOf(ext) == -1 ) {
return true;
} else {
__error__(KindEditor.tmpl(options.lang.invalidExt, {invalidExt:ext}), node);
return false;
}
}
//获取文件后缀名
function getFileExt(filename) {
if ( !filename ) return false;
var position = filename.lastIndexOf('.')
if ( position != -1 ) {
return filename.substr(position+1).toLowerCase();
}
return false;
}
//获取可接受的文件后缀
function getAccept() {
var extensions = options.ext_allow.split("|");
var accept = [];
$.each(extensions, function(idx, item) {
accept.push(mimeType[item]);
});
if ( accept.length > 1 ) {
return accept.uinque().join(",");
}
return "*";
}
//显示上传错误信息
function __error__(message, node) {
G("#img-comtainer-"+dialogSCode+ node.index).find(".error").show().text(message);
}
//query
function G(query) {
return o.dialog.find(query);
}
//从服务器上获取图片地址
function loadFilesFromServer() {
if ( !options.list_url ) {
G(".online .no-data").html('<span class="error">'+options.lang.noListUrl+'</span>').show();
return false;
}
if ( o.noRecord ) return false;
G(".loading-icon").show(); //显示加载图标
$.get(options.list_url, {
page : o.page,
marker : o.marker,
fileType : options.fileType,
}, function(res) {
G(".loading-icon").hide(); //隐藏加载图标
if ( res.code == "000" ) {
if (!res.data[0]) { //没有加载到数据
G(".online .no-data").text(options.lang.noDataText).show();
return;
}
o.marker = res.extra; //存储marker
o.page++;
appendFiles(res.data, "online");
} else {
G(".online .no-data").text(options.lang.noDataText).show();
o.noRecord = true;
}
}, "json");
}
//追加元素到图片列表
function appendFiles(data, module) {
$.each(data, function(idx, item) {
var builder = new StringBuilder();
builder.append('<li>');
var extension = getFileExt(item.thumbURL);
if ( extension == '' ) extension = "default";
extension = extension.toLowerCase();
//如果不是图片,则根据文件的后缀名去加载对应的缩略图
var imgSize = item.width+'x'+item.height; //图片尺寸
if ( "jpg|jpeg|gif|png|bmp".indexOf(extension) == -1 ) {
imgSize = formatFileSize(item.filesize); //如果是文件则显示文件大小
builder.append('<span class="icon-placeholder icon-'+extension+'" data-src="'+item.oriURL+'"></span>');
} else {
builder.append('<img src="'+item.thumbURL+'" data-src="'+item.oriURL+'" border="0">');
}
builder.append('<span class="ic" data-module="'+module+'"><em class="img-size">'+imgSize+'</em></span></li>');
var $image = $(builder.toString());
//绑定选择图片事件
$image.find(".ic").on("click", function() {
var src = $(this).prev().data("src");
var module = $(this).data("module");
if ( $(this).hasClass("selected") ) {
$(this).removeClass("selected");
} else {
$(this).addClass("selected");
o.selectedList.push(src);
}
//console.log(o.selectedList);
});
//裁剪显示图片
$image.find("img").imageCrop(113, 113);
if ( module == "online" ) {
G(".imagelist .list").append($image);
} else if ( module == "search" ) {
G(".search-imagelist-box .search-list").append($image);
}
});
}
//initialize dialog
createDialog();
bindEvent();
return o;
}; //end of JUpload
//string builder
var StringBuilder = function() {
var buffer = new Array();
StringBuilder.prototype.append = function(str) {
buffer.push(str);
}
StringBuilder.prototype.toString = function () {
return buffer.join("");
}
}
})(jQuery);