229 lines
6.0 KiB
JavaScript
229 lines
6.0 KiB
JavaScript
/**
|
||
* @fileOverview 各种验证,包括文件总大小是否超出、单文件是否超出和文件是否重复。
|
||
*/
|
||
|
||
define([
|
||
'../base',
|
||
'../uploader',
|
||
'../file',
|
||
'./widget'
|
||
], function( Base, Uploader, WUFile ) {
|
||
|
||
var $ = Base.$,
|
||
validators = {},
|
||
api;
|
||
|
||
/**
|
||
* @event error
|
||
* @param {String} type 错误类型。
|
||
* @description 当validate不通过时,会以派送错误事件的形式通知调用者。通过`upload.on('error', handler)`可以捕获到此类错误,目前有以下错误会在特定的情况下派送错来。
|
||
*
|
||
* * `Q_EXCEED_NUM_LIMIT` 在设置了`fileNumLimit`且尝试给`uploader`添加的文件数量超出这个值时派送。
|
||
* * `Q_EXCEED_SIZE_LIMIT` 在设置了`Q_EXCEED_SIZE_LIMIT`且尝试给`uploader`添加的文件总大小超出这个值时派送。
|
||
* * `Q_TYPE_DENIED` 当文件类型不满足时触发。。
|
||
* @for Uploader
|
||
*/
|
||
|
||
// 暴露给外面的api
|
||
api = {
|
||
|
||
// 添加验证器
|
||
addValidator: function( type, cb ) {
|
||
validators[ type ] = cb;
|
||
},
|
||
|
||
// 移除验证器
|
||
removeValidator: function( type ) {
|
||
delete validators[ type ];
|
||
}
|
||
};
|
||
|
||
// 在Uploader初始化的时候启动Validators的初始化
|
||
Uploader.register({
|
||
name: 'validator',
|
||
|
||
init: function() {
|
||
var me = this;
|
||
Base.nextTick(function() {
|
||
$.each( validators, function() {
|
||
this.call( me.owner );
|
||
});
|
||
});
|
||
}
|
||
});
|
||
|
||
/**
|
||
* @property {int} [fileNumLimit=undefined]
|
||
* @namespace options
|
||
* @for Uploader
|
||
* @description 验证文件总数量, 超出则不允许加入队列。
|
||
*/
|
||
api.addValidator( 'fileNumLimit', function() {
|
||
var uploader = this,
|
||
opts = uploader.options,
|
||
count = 0,
|
||
max = parseInt( opts.fileNumLimit, 10 ),
|
||
flag = true;
|
||
|
||
if ( !max ) {
|
||
return;
|
||
}
|
||
|
||
uploader.on( 'beforeFileQueued', function( file ) {
|
||
|
||
if ( count >= max && flag ) {
|
||
flag = false;
|
||
this.trigger( 'error', 'Q_EXCEED_NUM_LIMIT', max, file );
|
||
setTimeout(function() {
|
||
flag = true;
|
||
}, 1 );
|
||
}
|
||
|
||
return count >= max ? false : true;
|
||
});
|
||
|
||
uploader.on( 'fileQueued', function() {
|
||
count++;
|
||
});
|
||
|
||
uploader.on( 'fileDequeued', function() {
|
||
count--;
|
||
});
|
||
|
||
uploader.on( 'reset', function() {
|
||
count = 0;
|
||
});
|
||
});
|
||
|
||
|
||
/**
|
||
* @property {int} [fileSizeLimit=undefined]
|
||
* @namespace options
|
||
* @for Uploader
|
||
* @description 验证文件总大小是否超出限制, 超出则不允许加入队列。
|
||
*/
|
||
api.addValidator( 'fileSizeLimit', function() {
|
||
var uploader = this,
|
||
opts = uploader.options,
|
||
count = 0,
|
||
max = parseInt( opts.fileSizeLimit, 10 ),
|
||
flag = true;
|
||
|
||
if ( !max ) {
|
||
return;
|
||
}
|
||
|
||
uploader.on( 'beforeFileQueued', function( file ) {
|
||
var invalid = count + file.size > max;
|
||
|
||
if ( invalid && flag ) {
|
||
flag = false;
|
||
this.trigger( 'error', 'Q_EXCEED_SIZE_LIMIT', max, file );
|
||
setTimeout(function() {
|
||
flag = true;
|
||
}, 1 );
|
||
}
|
||
|
||
return invalid ? false : true;
|
||
});
|
||
|
||
uploader.on( 'fileQueued', function( file ) {
|
||
count += file.size;
|
||
});
|
||
|
||
uploader.on( 'fileDequeued', function( file ) {
|
||
count -= file.size;
|
||
});
|
||
|
||
uploader.on( 'reset', function() {
|
||
count = 0;
|
||
});
|
||
});
|
||
|
||
/**
|
||
* @property {int} [fileSingleSizeLimit=undefined]
|
||
* @namespace options
|
||
* @for Uploader
|
||
* @description 验证单个文件大小是否超出限制, 超出则不允许加入队列。
|
||
*/
|
||
api.addValidator( 'fileSingleSizeLimit', function() {
|
||
var uploader = this,
|
||
opts = uploader.options,
|
||
max = opts.fileSingleSizeLimit;
|
||
|
||
if ( !max ) {
|
||
return;
|
||
}
|
||
|
||
uploader.on( 'beforeFileQueued', function( file ) {
|
||
|
||
if ( file.size > max ) {
|
||
file.setStatus( WUFile.Status.INVALID, 'exceed_size' );
|
||
this.trigger( 'error', 'F_EXCEED_SIZE', max, file );
|
||
return false;
|
||
}
|
||
|
||
});
|
||
|
||
});
|
||
|
||
/**
|
||
* @property {Boolean} [duplicate=undefined]
|
||
* @namespace options
|
||
* @for Uploader
|
||
* @description 去重, 根据文件名字、文件大小和最后修改时间来生成hash Key.
|
||
*/
|
||
api.addValidator( 'duplicate', function() {
|
||
var uploader = this,
|
||
opts = uploader.options,
|
||
mapping = {};
|
||
|
||
if ( opts.duplicate ) {
|
||
return;
|
||
}
|
||
|
||
function hashString( str ) {
|
||
var hash = 0,
|
||
i = 0,
|
||
len = str.length,
|
||
_char;
|
||
|
||
for ( ; i < len; i++ ) {
|
||
_char = str.charCodeAt( i );
|
||
hash = _char + (hash << 6) + (hash << 16) - hash;
|
||
}
|
||
|
||
return hash;
|
||
}
|
||
|
||
uploader.on( 'beforeFileQueued', function( file ) {
|
||
var hash = file.__hash || (file.__hash = hashString( file.name +
|
||
file.size + file.lastModifiedDate ));
|
||
|
||
// 已经重复了
|
||
if ( mapping[ hash ] ) {
|
||
this.trigger( 'error', 'F_DUPLICATE', file );
|
||
return false;
|
||
}
|
||
});
|
||
|
||
uploader.on( 'fileQueued', function( file ) {
|
||
var hash = file.__hash;
|
||
|
||
hash && (mapping[ hash ] = true);
|
||
});
|
||
|
||
uploader.on( 'fileDequeued', function( file ) {
|
||
var hash = file.__hash;
|
||
|
||
hash && (delete mapping[ hash ]);
|
||
});
|
||
|
||
uploader.on( 'reset', function() {
|
||
mapping = {};
|
||
});
|
||
});
|
||
|
||
return api;
|
||
});
|