/** * @fileoverview 上传组件主题基类 * @author 剑平(明河) **/ KISSY.add('gallery/form/1.3/uploader/theme', function (S, Node, Base) { var EMPTY = '', $ = Node.all, //主题样式名前缀 classSuffix = {BUTTON:'-button', QUEUE:'-queue'}; /** * @name Theme * @class 上传组件主题基类 * @constructor * @extends Base * @requires Queue */ function Theme(config) { var self = this; //调用父类构造函数 Theme.superclass.constructor.call(self, config); } S.extend(Theme, Base, /** @lends Theme.prototype*/{ /** * 组件运行 */ render:function(){ var self = this; self._LoaderCss(function(){ self._addThemeCssName(); self.fire('render'); }); }, /** * 在上传组件运行完毕后执行的方法(对上传组件所有的控制都应该在这个函数内) * @param {Uploader} uploader */ afterUploaderRender:function (uploader) { }, /** * 获取状态容器 * @param {KISSY.NodeList} target 文件的对应的dom(一般是li元素) * @return {KISSY.NodeList} */ _getStatusWrapper:function (target) { return target && target.children('.J_FileStatus') || $(''); }, /** * 控制文件对应的li元素的显影 * @param {Boolean} isShow 是否认显示 * @param {NodeList} target li元素 * @param {Function} callback 回调 */ displayFile:function (isShow, target, callback) { var self = this, duration = self.get('duration'); if (!target || !target.length) return false; target[isShow && 'fadeIn' || 'fadeOut'](duration, function () { callback && callback.call(self); }); }, /** * 文件处于等待上传状态时触发 */ _waitingHandler:function (ev) { }, /** * 文件处于开始上传状态时触发 */ _startHandler:function (ev) { }, /** * 文件处于正在上传状态时触发 */ _progressHandler:function (ev) { }, /** * 文件处于上传成功状态时触发 */ _successHandler:function (ev) { }, /** * 文件处于上传错误状态时触发 */ _errorHandler:function (ev) { }, /** * 从路径隐藏域抓取文件,往队列添加文件后触发 * @param ev */ _restoreHandler:function (ev) { }, /** * uploader实例化后执行 */ _UploaderRender:function (callback) { var self = this; self._initQueue(); //加载插件 self._loadPlugins(callback); }, /** * 将主题名写入到队列和按钮目标容器,作为主题css样式起始 */ _addThemeCssName:function () { var self = this, name = self.get('name'), $queueTarget = $(self.get('queueTarget')), $btn = $(self.get('buttonTarget')); if (name == EMPTY) return false; if($queueTarget.length) $queueTarget.addClass(name + classSuffix.QUEUE); $btn.addClass(name + classSuffix.BUTTON); }, /** * 初始化队列 * @return {Queue} */ _initQueue:function () { var self = this, queue = self.get('queue'); queue.set('fnAdd',function(index, file){ return self._addCallback(index, file); }); queue.set('theme', self); queue.on('add', self._addFileHandler, self); queue.on('remove', self._removeFileHandler, self); queue.on('statusChange', function (ev) { self._setStatusVisibility(ev); }); return queue; }, /** * 加载css文件 */ _LoaderCss:function (callback) { var self = this, cssUrl = self.get('cssUrl'); //加载css文件 if (cssUrl == EMPTY){ callback.call(self); return false; } S.use(cssUrl, function () { S.log(cssUrl + '加载成功!'); callback.call(self); }); }, /** * 向队列添加完文件后触发的回调函数(在add事件前触发) * @param {Number} index 文件索引值 * @param {Object} file 文件数据 * @return {Object} file */ _addCallback:function (index, file) { var self = this, queue = self.get('queue'), $target = self._appendFileDom(file); //将状态层容器写入到file数据 queue.updateFile(index, { target:$target, statusWrapper:self._getStatusWrapper($target) }); //更换文件状态为等待 queue.fileStatus(index,'waiting'); self.displayFile(true, $target); //给li下的按钮元素绑定事件 // TODO 这里的绑定事件应该只是imageUploader这个主题的吧,不应该放在公共的Theme下 self._bindTriggerEvent(index, file); return queue.getFile(index); }, /** * 删除队列中的文件后触发的监听器 */ _removeFileHandler:function (ev) { var self = this, file = ev.file; self.displayFile(false, file.target); }, /** * 给删除、上传、取消等按钮元素绑定事件 * TODO 这个是不是也应该放在imageUploader里面呢? * @param {Number} index 文件索引值 * @param {Object} 文件数据 */ _bindTriggerEvent:function (index, file) { var self = this, queue = self.get('queue'), uploader = self.get('uploader'), //文件id fileId = file.id, //上传链接 $upload = $('.J_Upload_' + fileId), //取消链接 $cancel = $('.J_Cancel_' + fileId), //删除链接 $del = $(".J_Del_" + fileId); //点击上传 $upload.on('click', function (ev) { ev.preventDefault(); if (!S.isObject(uploader)) return false; uploader.upload(index); }); //点击取消 $cancel.on('click', function (ev) { ev.preventDefault(); uploader.cancel(index); }); //点击删除 $del.on('click', function (ev) { ev.preventDefault(); //删除队列中的文件 queue.remove(fileId); }); }, /** * 设置状态层的可见性 * @param ev */ _setStatusVisibility:function (ev) { var $statusWrapper = ev.file.statusWrapper, $status, file = ev.file, status = file.status; if (!$statusWrapper || !$statusWrapper.length) { S.log('状态容器层不存在!'); return false; } $status = $statusWrapper.children('.status'); $status.hide(); $statusWrapper.children('.' + status + '-status').show(); var $target = file.target; var statuses = ['waiting','start','uploading','progress','error','success']; S.each(statuses,function(status){ $target.removeClass(status); }); $target.addClass(status); }, /** * 当队列添加完文件数据后向队列容器插入文件信息DOM结构 * @param {Object} fileData 文件数据 * @return {KISSY.NodeList} */ _appendFileDom:function (fileData) { var self = this, tpl = self.get('fileTpl'), $target = $(self.get('queueTarget')), hFile; if (!$target.length) return false; hFile = S.substitute(tpl, fileData); return $(hFile).hide().appendTo($target).data('data-file', fileData); }, /** * 根据插件配置加载插件 */ _loadPlugins:function(callback){ var self = this, plugins = self.get('plugins'), oPlugin = self.get('oPlugin'), //模块路径前缀 modPrefix = 'gallery/form/1.3/uploader/plugins/', mods = []; if(!plugins.length){ callback && callback.call(self,oPlugin); return false; } //拼接模块路径 S.each(plugins,function(plugin){ mods.push(modPrefix+plugin+'/' +plugin); }); S.use(mods.join(','),function(){ S.each(arguments,function(arg,i){ // 类排除S if(i>=1) oPlugin[plugins[i-1]] = arg; }); self.set('oPlugin',oPlugin); callback && callback.call(self,oPlugin); }) } }, {ATTRS:/** @lends Theme.prototype*/{ /** * 主题名 * @type String * @default "" */ name:{value:EMPTY}, /** * css模块路径 * @type String * @default "" */ cssUrl:{value:EMPTY}, /** * 队列使用的模板 * @type String * @default "" */ fileTpl:{value:EMPTY }, /** * 需要加载的插件,需要手动实例化 * @type Array * @default [] */ plugins:{value:[]}, /** * 插件类集合 * @type Array * @default [] */ oPlugin:{value:{}}, /** * 队列目标元素(一般是ul),队列的实例化过程在Theme中 * @type String * @default "" */ queueTarget:{value:EMPTY}, /** * 动画速度 * @type Number * @default 0.3 */ duration:{value:0.3}, /** * Queue(上传队列)实例 * @type Queue * @default "" */ queue:{value:EMPTY}, /** * Uploader 上传组件实例 * @type Uploader * @default "" */ uploader:{value:EMPTY}, /** * Button 按钮实例(_init()下并不存在) * @type Button * @default "" */ button:{value:EMPTY}, /** * Auth(上传验证)实例 * @type Auth * @default "" */ auth:{value:EMPTY} }}); return Theme; }, {requires:['node', 'base']});