qc.ifish7.com/Public/webuploader/widgets/queue.js

309 lines
9.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @fileOverview 队列
*/
define([
'../base',
'../uploader',
'../queue',
'../file',
'../lib/file',
'../runtime/client',
'./widget'
], function( Base, Uploader, Queue, WUFile, File, RuntimeClient ) {
var $ = Base.$,
rExt = /\.\w+$/,
Status = WUFile.Status;
return Uploader.register({
name: 'queue',
init: function( opts ) {
var me = this,
deferred, len, i, item, arr, accept, runtime;
if ( $.isPlainObject( opts.accept ) ) {
opts.accept = [ opts.accept ];
}
// accept中的中生成匹配正则。
if ( opts.accept ) {
arr = [];
for ( i = 0, len = opts.accept.length; i < len; i++ ) {
item = opts.accept[ i ].extensions;
item && arr.push( item );
}
if ( arr.length ) {
accept = '\\.' + arr.join(',')
.replace( /,/g, '$|\\.' )
.replace( /\*/g, '.*' ) + '$';
}
me.accept = new RegExp( accept, 'i' );
}
me.queue = new Queue();
me.stats = me.queue.stats;
// 如果当前不是html5运行时那就算了。
// 不执行后续操作
if ( this.request('predict-runtime-type') !== 'html5' ) {
return;
}
// 创建一个 html5 运行时的 placeholder
// 以至于外部添加原生 File 对象的时候能正确包裹一下供 webuploader 使用。
deferred = Base.Deferred();
this.placeholder = runtime = new RuntimeClient('Placeholder');
runtime.connectRuntime({
runtimeOrder: 'html5'
}, function() {
me._ruid = runtime.getRuid();
deferred.resolve();
});
return deferred.promise();
},
// 为了支持外部直接添加一个原生File对象。
_wrapFile: function( file ) {
if ( !(file instanceof WUFile) ) {
if ( !(file instanceof File) ) {
if ( !this._ruid ) {
throw new Error('Can\'t add external files.');
}
file = new File( this._ruid, file );
}
file = new WUFile( file );
}
return file;
},
// 判断文件是否可以被加入队列
acceptFile: function( file ) {
var invalid = !file || !file.size || this.accept &&
// 如果名字中有后缀,才做后缀白名单处理。
rExt.exec( file.name ) && !this.accept.test( file.name );
return !invalid;
},
/**
* @event beforeFileQueued
* @param {File} file File对象
* @description 当文件被加入队列之前触发此事件的handler返回值为`false`,则此文件不会被添加进入队列。
* @for Uploader
*/
/**
* @event fileQueued
* @param {File} file File对象
* @description 当文件被加入队列以后触发。
* @for Uploader
*/
_addFile: function( file ) {
var me = this;
file = me._wrapFile( file );
// 不过类型判断允许不允许,先派送 `beforeFileQueued`
if ( !me.owner.trigger( 'beforeFileQueued', file ) ) {
return;
}
// 类型不匹配,则派送错误事件,并返回。
if ( !me.acceptFile( file ) ) {
me.owner.trigger( 'error', 'Q_TYPE_DENIED', file );
return;
}
me.queue.append( file );
me.owner.trigger( 'fileQueued', file );
return file;
},
getFile: function( fileId ) {
return this.queue.getFile( fileId );
},
/**
* @event filesQueued
* @param {File} files 数组内容为原始File(lib/File对象。
* @description 当一批文件添加进队列以后触发。
* @for Uploader
*/
/**
* @property {Boolean} [auto=false]
* @namespace options
* @for Uploader
* @description 设置为 true 后,不需要手动调用上传,有文件选择即开始上传。
*
*/
/**
* @method addFiles
* @grammar addFiles( file ) => undefined
* @grammar addFiles( [file1, file2 ...] ) => undefined
* @param {Array of File or File} [files] Files 对象 数组
* @description 添加文件到队列
* @for Uploader
*/
addFile: function( files ) {
var me = this;
if ( !files.length ) {
files = [ files ];
}
files = $.map( files, function( file ) {
return me._addFile( file );
});
if ( files.length ) {
me.owner.trigger( 'filesQueued', files );
if ( me.options.auto ) {
setTimeout(function() {
me.request('start-upload');
}, 20 );
}
}
},
getStats: function() {
return this.stats;
},
/**
* @event fileDequeued
* @param {File} file File对象
* @description 当文件被移除队列后触发。
* @for Uploader
*/
/**
* @method removeFile
* @grammar removeFile( file ) => undefined
* @grammar removeFile( id ) => undefined
* @grammar removeFile( file, true ) => undefined
* @grammar removeFile( id, true ) => undefined
* @param {File|id} file File对象或这File对象的id
* @description 移除某一文件, 默认只会标记文件状态为已取消,如果第二个参数为 `true` 则会从 queue 中移除。
* @for Uploader
* @example
*
* $li.on('click', '.remove-this', function() {
* uploader.removeFile( file );
* })
*/
removeFile: function( file, remove ) {
var me = this;
file = file.id ? file : me.queue.getFile( file );
this.request( 'cancel-file', file );
if ( remove ) {
this.queue.removeFile( file );
}
},
/**
* @method getFiles
* @grammar getFiles() => Array
* @grammar getFiles( status1, status2, status... ) => Array
* @description 返回指定状态的文件集合,不传参数将返回所有状态的文件。
* @for Uploader
* @example
* console.log( uploader.getFiles() ); // => all files
* console.log( uploader.getFiles('error') ) // => all error files.
*/
getFiles: function() {
return this.queue.getFiles.apply( this.queue, arguments );
},
fetchFile: function() {
return this.queue.fetch.apply( this.queue, arguments );
},
/**
* @method retry
* @grammar retry() => undefined
* @grammar retry( file ) => undefined
* @description 重试上传,重试指定文件,或者从出错的文件开始重新上传。
* @for Uploader
* @example
* function retry() {
* uploader.retry();
* }
*/
retry: function( file, noForceStart ) {
var me = this,
files, i, len;
if ( file ) {
file = file.id ? file : me.queue.getFile( file );
file.setStatus( Status.QUEUED );
noForceStart || me.request('start-upload');
return;
}
files = me.queue.getFiles( Status.ERROR );
i = 0;
len = files.length;
for ( ; i < len; i++ ) {
file = files[ i ];
file.setStatus( Status.QUEUED );
}
me.request('start-upload');
},
/**
* @method sort
* @grammar sort( fn ) => undefined
* @description 排序队列中的文件,在上传之前调整可以控制上传顺序。
* @for Uploader
*/
sortFiles: function() {
return this.queue.sort.apply( this.queue, arguments );
},
/**
* @event reset
* @description 当 uploader 被重置的时候触发。
* @for Uploader
*/
/**
* @method reset
* @grammar reset() => undefined
* @description 重置uploader。目前只重置了队列。
* @for Uploader
* @example
* uploader.reset();
*/
reset: function() {
this.owner.trigger('reset');
this.queue = new Queue();
this.stats = this.queue.stats;
},
destroy: function() {
this.reset();
this.placeholder && this.placeholder.destroy();
}
});
});