From 59bfbce44674e52aefbe883233ffaea93d750a8f Mon Sep 17 00:00:00 2001 From: yujian <yujian@163.com> Date: 星期一, 25 十一月 2019 09:56:17 +0800 Subject: [PATCH] Merge branch 'div' of ssh://193.112.35.168:29418/fanli-server into div --- fanli/src/main/webapp/admin/new/js/third-party/webuploader/webuploader.js | 13466 +++++++++++++++++++++++++++++----------------------------- 1 files changed, 6,733 insertions(+), 6,733 deletions(-) diff --git a/fanli/src/main/webapp/admin/new/js/third-party/webuploader/webuploader.js b/fanli/src/main/webapp/admin/new/js/third-party/webuploader/webuploader.js index 39d9351..8526e4f 100644 --- a/fanli/src/main/webapp/admin/new/js/third-party/webuploader/webuploader.js +++ b/fanli/src/main/webapp/admin/new/js/third-party/webuploader/webuploader.js @@ -1,6733 +1,6733 @@ -/*! WebUploader 0.1.2 */ - - -/** - * @fileOverview 璁╁唴閮ㄥ悇涓儴浠剁殑浠g爜鍙互鐢╗amd](https://github.com/amdjs/amdjs-api/wiki/AMD)妯″潡瀹氫箟鏂瑰紡缁勭粐璧锋潵銆� - * - * AMD API 鍐呴儴鐨勭畝鍗曚笉瀹屽叏瀹炵幇锛岃蹇界暐銆傚彧鏈夊綋WebUploader琚悎骞舵垚涓�涓枃浠剁殑鏃跺�欐墠浼氬紩鍏ャ�� - */ -(function( root, factory ) { - var modules = {}, - - // 鍐呴儴require, 绠�鍗曚笉瀹屽叏瀹炵幇銆� - // https://github.com/amdjs/amdjs-api/wiki/require - _require = function( deps, callback ) { - var args, len, i; - - // 濡傛灉deps涓嶆槸鏁扮粍锛屽垯鐩存帴杩斿洖鎸囧畾module - if ( typeof deps === 'string' ) { - return getModule( deps ); - } else { - args = []; - for( len = deps.length, i = 0; i < len; i++ ) { - args.push( getModule( deps[ i ] ) ); - } - - return callback.apply( null, args ); - } - }, - - // 鍐呴儴define锛屾殏鏃朵笉鏀寔涓嶆寚瀹歩d. - _define = function( id, deps, factory ) { - if ( arguments.length === 2 ) { - factory = deps; - deps = null; - } - - _require( deps || [], function() { - setModule( id, factory, arguments ); - }); - }, - - // 璁剧疆module, 鍏煎CommonJs鍐欐硶銆� - setModule = function( id, factory, args ) { - var module = { - exports: factory - }, - returned; - - if ( typeof factory === 'function' ) { - args.length || (args = [ _require, module.exports, module ]); - returned = factory.apply( null, args ); - returned !== undefined && (module.exports = returned); - } - - modules[ id ] = module.exports; - }, - - // 鏍规嵁id鑾峰彇module - getModule = function( id ) { - var module = modules[ id ] || root[ id ]; - - if ( !module ) { - throw new Error( '`' + id + '` is undefined' ); - } - - return module; - }, - - // 灏嗘墍鏈塵odules锛屽皢璺緞ids瑁呮崲鎴愬璞°�� - exportsTo = function( obj ) { - var key, host, parts, part, last, ucFirst; - - // make the first character upper case. - ucFirst = function( str ) { - return str && (str.charAt( 0 ).toUpperCase() + str.substr( 1 )); - }; - - for ( key in modules ) { - host = obj; - - if ( !modules.hasOwnProperty( key ) ) { - continue; - } - - parts = key.split('/'); - last = ucFirst( parts.pop() ); - - while( (part = ucFirst( parts.shift() )) ) { - host[ part ] = host[ part ] || {}; - host = host[ part ]; - } - - host[ last ] = modules[ key ]; - } - }, - - exports = factory( root, _define, _require ), - origin; - - // exports every module. - exportsTo( exports ); - - if ( typeof module === 'object' && typeof module.exports === 'object' ) { - - // For CommonJS and CommonJS-like environments where a proper window is present, - module.exports = exports; - } else if ( typeof define === 'function' && define.amd ) { - - // Allow using this built library as an AMD module - // in another project. That other project will only - // see this AMD call, not the internal modules in - // the closure below. - define([], exports ); - } else { - - // Browser globals case. Just assign the - // result to a property on the global. - origin = root.WebUploader; - root.WebUploader = exports; - root.WebUploader.noConflict = function() { - root.WebUploader = origin; - }; - } -})( this, function( window, define, require ) { - - - /** - * @fileOverview jQuery or Zepto - */ - define('dollar-third',[],function() { - return window.jQuery || window.Zepto; - }); - /** - * @fileOverview Dom 鎿嶄綔鐩稿叧 - */ - define('dollar',[ - 'dollar-third' - ], function( _ ) { - return _; - }); - /** - * @fileOverview 浣跨敤jQuery鐨凱romise - */ - define('promise-third',[ - 'dollar' - ], function( $ ) { - return { - Deferred: $.Deferred, - when: $.when, - - isPromise: function( anything ) { - return anything && typeof anything.then === 'function'; - } - }; - }); - /** - * @fileOverview Promise/A+ - */ - define('promise',[ - 'promise-third' - ], function( _ ) { - return _; - }); - /** - * @fileOverview 鍩虹绫绘柟娉曘�� - */ - - /** - * Web Uploader鍐呴儴绫荤殑璇︾粏璇存槑锛屼互涓嬫彁鍙婄殑鍔熻兘绫伙紝閮藉彲浠ュ湪`WebUploader`杩欎釜鍙橀噺涓闂埌銆� - * - * As you know, Web Uploader鐨勬瘡涓枃浠堕兘鏄敤杩嘯AMD](https://github.com/amdjs/amdjs-api/wiki/AMD)瑙勮寖涓殑`define`缁勭粐璧锋潵鐨�, 姣忎釜Module閮戒細鏈変釜module id. - * 榛樿module id璇ユ枃浠剁殑璺緞锛岃�屾璺緞灏嗕細杞寲鎴愬悕瀛楃┖闂村瓨鏀惧湪WebUploader涓�傚锛� - * - * * module `base`锛歐ebUploader.Base - * * module `file`: WebUploader.File - * * module `lib/dnd`: WebUploader.Lib.Dnd - * * module `runtime/html5/dnd`: WebUploader.Runtime.Html5.Dnd - * - * - * 浠ヤ笅鏂囨。灏嗗彲鑳界渷鐣WebUploader`鍓嶇紑銆� - * @module WebUploader - * @title WebUploader API鏂囨。 - */ - define('base',[ - 'dollar', - 'promise' - ], function( $, promise ) { - - var noop = function() {}, - call = Function.call; - - // http://jsperf.com/uncurrythis - // 鍙嶇閲屽寲 - function uncurryThis( fn ) { - return function() { - return call.apply( fn, arguments ); - }; - } - - function bindFn( fn, context ) { - return function() { - return fn.apply( context, arguments ); - }; - } - - function createObject( proto ) { - var f; - - if ( Object.create ) { - return Object.create( proto ); - } else { - f = function() {}; - f.prototype = proto; - return new f(); - } - } - - - /** - * 鍩虹绫伙紝鎻愪緵涓�浜涚畝鍗曞父鐢ㄧ殑鏂规硶銆� - * @class Base - */ - return { - - /** - * @property {String} version 褰撳墠鐗堟湰鍙枫�� - */ - version: '0.1.2', - - /** - * @property {jQuery|Zepto} $ 寮曠敤渚濊禆鐨刯Query鎴栬�匷epto瀵硅薄銆� - */ - $: $, - - Deferred: promise.Deferred, - - isPromise: promise.isPromise, - - when: promise.when, - - /** - * @description 绠�鍗曠殑娴忚鍣ㄦ鏌ョ粨鏋溿�� - * - * * `webkit` webkit鐗堟湰鍙凤紝濡傛灉娴忚鍣ㄤ负闈瀢ebkit鍐呮牳锛屾灞炴�т负`undefined`銆� - * * `chrome` chrome娴忚鍣ㄧ増鏈彿锛屽鏋滄祻瑙堝櫒涓篶hrome锛屾灞炴�т负`undefined`銆� - * * `ie` ie娴忚鍣ㄧ増鏈彿锛屽鏋滄祻瑙堝櫒涓洪潪ie锛屾灞炴�т负`undefined`銆�**鏆備笉鏀寔ie10+** - * * `firefox` firefox娴忚鍣ㄧ増鏈彿锛屽鏋滄祻瑙堝櫒涓洪潪firefox锛屾灞炴�т负`undefined`銆� - * * `safari` safari娴忚鍣ㄧ増鏈彿锛屽鏋滄祻瑙堝櫒涓洪潪safari锛屾灞炴�т负`undefined`銆� - * * `opera` opera娴忚鍣ㄧ増鏈彿锛屽鏋滄祻瑙堝櫒涓洪潪opera锛屾灞炴�т负`undefined`銆� - * - * @property {Object} [browser] - */ - browser: (function( ua ) { - var ret = {}, - webkit = ua.match( /WebKit\/([\d.]+)/ ), - chrome = ua.match( /Chrome\/([\d.]+)/ ) || - ua.match( /CriOS\/([\d.]+)/ ), - - ie = ua.match( /MSIE\s([\d\.]+)/ ) || - ua.match(/(?:trident)(?:.*rv:([\w.]+))?/i), - firefox = ua.match( /Firefox\/([\d.]+)/ ), - safari = ua.match( /Safari\/([\d.]+)/ ), - opera = ua.match( /OPR\/([\d.]+)/ ); - - webkit && (ret.webkit = parseFloat( webkit[ 1 ] )); - chrome && (ret.chrome = parseFloat( chrome[ 1 ] )); - ie && (ret.ie = parseFloat( ie[ 1 ] )); - firefox && (ret.firefox = parseFloat( firefox[ 1 ] )); - safari && (ret.safari = parseFloat( safari[ 1 ] )); - opera && (ret.opera = parseFloat( opera[ 1 ] )); - - return ret; - })( navigator.userAgent ), - - /** - * @description 鎿嶄綔绯荤粺妫�鏌ョ粨鏋溿�� - * - * * `android` 濡傛灉鍦╝ndroid娴忚鍣ㄧ幆澧冧笅锛屾鍊间负瀵瑰簲鐨刟ndroid鐗堟湰鍙凤紝鍚﹀垯涓篳undefined`銆� - * * `ios` 濡傛灉鍦╥os娴忚鍣ㄧ幆澧冧笅锛屾鍊间负瀵瑰簲鐨刬os鐗堟湰鍙凤紝鍚﹀垯涓篳undefined`銆� - * @property {Object} [os] - */ - os: (function( ua ) { - var ret = {}, - - // osx = !!ua.match( /\(Macintosh\; Intel / ), - android = ua.match( /(?:Android);?[\s\/]+([\d.]+)?/ ), - ios = ua.match( /(?:iPad|iPod|iPhone).*OS\s([\d_]+)/ ); - - // osx && (ret.osx = true); - android && (ret.android = parseFloat( android[ 1 ] )); - ios && (ret.ios = parseFloat( ios[ 1 ].replace( /_/g, '.' ) )); - - return ret; - })( navigator.userAgent ), - - /** - * 瀹炵幇绫讳笌绫讳箣闂寸殑缁ф壙銆� - * @method inherits - * @grammar Base.inherits( super ) => child - * @grammar Base.inherits( super, protos ) => child - * @grammar Base.inherits( super, protos, statics ) => child - * @param {Class} super 鐖剁被 - * @param {Object | Function} [protos] 瀛愮被鎴栬�呭璞°�傚鏋滃璞′腑鍖呭惈constructor锛屽瓙绫诲皢鏄敤姝ゅ睘鎬у�笺�� - * @param {Function} [protos.constructor] 瀛愮被鏋勯�犲櫒锛屼笉鎸囧畾鐨勮瘽灏嗗垱寤轰釜涓存椂鐨勭洿鎺ユ墽琛岀埗绫绘瀯閫犲櫒鐨勬柟娉曘�� - * @param {Object} [statics] 闈欐�佸睘鎬ф垨鏂规硶銆� - * @return {Class} 杩斿洖瀛愮被銆� - * @example - * function Person() { - * console.log( 'Super' ); - * } - * Person.prototype.hello = function() { - * console.log( 'hello' ); - * }; - * - * var Manager = Base.inherits( Person, { - * world: function() { - * console.log( 'World' ); - * } - * }); - * - * // 鍥犱负娌℃湁鎸囧畾鏋勯�犲櫒锛岀埗绫荤殑鏋勯�犲櫒灏嗕細鎵ц銆� - * var instance = new Manager(); // => Super - * - * // 缁ф壙瀛愮埗绫荤殑鏂规硶 - * instance.hello(); // => hello - * instance.world(); // => World - * - * // 瀛愮被鐨刜_super__灞炴�ф寚鍚戠埗绫� - * console.log( Manager.__super__ === Person ); // => true - */ - inherits: function( Super, protos, staticProtos ) { - var child; - - if ( typeof protos === 'function' ) { - child = protos; - protos = null; - } else if ( protos && protos.hasOwnProperty('constructor') ) { - child = protos.constructor; - } else { - child = function() { - return Super.apply( this, arguments ); - }; - } - - // 澶嶅埗闈欐�佹柟娉� - $.extend( true, child, Super, staticProtos || {} ); - - /* jshint camelcase: false */ - - // 璁╁瓙绫荤殑__super__灞炴�ф寚鍚戠埗绫汇�� - child.__super__ = Super.prototype; - - // 鏋勫缓鍘熷瀷锛屾坊鍔犲師鍨嬫柟娉曟垨灞炴�с�� - // 鏆傛椂鐢∣bject.create瀹炵幇銆� - child.prototype = createObject( Super.prototype ); - protos && $.extend( true, child.prototype, protos ); - - return child; - }, - - /** - * 涓�涓笉鍋氫换浣曚簨鎯呯殑鏂规硶銆傚彲浠ョ敤鏉ヨ祴鍊肩粰榛樿鐨刢allback. - * @method noop - */ - noop: noop, - - /** - * 杩斿洖涓�涓柊鐨勬柟娉曪紝姝ゆ柟娉曞皢宸叉寚瀹氱殑`context`鏉ユ墽琛屻�� - * @grammar Base.bindFn( fn, context ) => Function - * @method bindFn - * @example - * var doSomething = function() { - * console.log( this.name ); - * }, - * obj = { - * name: 'Object Name' - * }, - * aliasFn = Base.bind( doSomething, obj ); - * - * aliasFn(); // => Object Name - * - */ - bindFn: bindFn, - - /** - * 寮曠敤Console.log濡傛灉瀛樺湪鐨勮瘽锛屽惁鍒欏紩鐢ㄤ竴涓猍绌哄嚱鏁發oop](#WebUploader:Base.log)銆� - * @grammar Base.log( args... ) => undefined - * @method log - */ - log: (function() { - if ( window.console ) { - return bindFn( console.log, console ); - } - return noop; - })(), - - nextTick: (function() { - - return function( cb ) { - setTimeout( cb, 1 ); - }; - - // @bug 褰撴祻瑙堝櫒涓嶅湪褰撳墠绐楀彛鏃跺氨鍋滀簡銆� - // var next = window.requestAnimationFrame || - // window.webkitRequestAnimationFrame || - // window.mozRequestAnimationFrame || - // function( cb ) { - // window.setTimeout( cb, 1000 / 60 ); - // }; - - // // fix: Uncaught TypeError: Illegal invocation - // return bindFn( next, window ); - })(), - - /** - * 琚玔uncurrythis](http://www.2ality.com/2011/11/uncurrying-this.html)鐨勬暟缁剆lice鏂规硶銆� - * 灏嗙敤鏉ュ皢闈炴暟缁勫璞¤浆鍖栨垚鏁扮粍瀵硅薄銆� - * @grammar Base.slice( target, start[, end] ) => Array - * @method slice - * @example - * function doSomthing() { - * var args = Base.slice( arguments, 1 ); - * console.log( args ); - * } - * - * doSomthing( 'ignored', 'arg2', 'arg3' ); // => Array ["arg2", "arg3"] - */ - slice: uncurryThis( [].slice ), - - /** - * 鐢熸垚鍞竴鐨処D - * @method guid - * @grammar Base.guid() => String - * @grammar Base.guid( prefx ) => String - */ - guid: (function() { - var counter = 0; - - return function( prefix ) { - var guid = (+new Date()).toString( 32 ), - i = 0; - - for ( ; i < 5; i++ ) { - guid += Math.floor( Math.random() * 65535 ).toString( 32 ); - } - - return (prefix || 'wu_') + guid + (counter++).toString( 32 ); - }; - })(), - - /** - * 鏍煎紡鍖栨枃浠跺ぇ灏�, 杈撳嚭鎴愬甫鍗曚綅鐨勫瓧绗︿覆 - * @method formatSize - * @grammar Base.formatSize( size ) => String - * @grammar Base.formatSize( size, pointLength ) => String - * @grammar Base.formatSize( size, pointLength, units ) => String - * @param {Number} size 鏂囦欢澶у皬 - * @param {Number} [pointLength=2] 绮剧‘鍒扮殑灏忔暟鐐规暟銆� - * @param {Array} [units=[ 'B', 'K', 'M', 'G', 'TB' ]] 鍗曚綅鏁扮粍銆備粠瀛楄妭锛屽埌鍗冨瓧鑺傦紝涓�鐩村線涓婃寚瀹氥�傚鏋滃崟浣嶆暟缁勯噷闈㈠彧鎸囧畾浜嗗埌浜咾(鍗冨瓧鑺�)锛屽悓鏃舵枃浠跺ぇ灏忓ぇ浜嶮, 姝ゆ柟娉曠殑杈撳嚭灏嗚繕鏄樉绀烘垚澶氬皯K. - * @example - * console.log( Base.formatSize( 100 ) ); // => 100B - * console.log( Base.formatSize( 1024 ) ); // => 1.00K - * console.log( Base.formatSize( 1024, 0 ) ); // => 1K - * console.log( Base.formatSize( 1024 * 1024 ) ); // => 1.00M - * console.log( Base.formatSize( 1024 * 1024 * 1024 ) ); // => 1.00G - * console.log( Base.formatSize( 1024 * 1024 * 1024, 0, ['B', 'KB', 'MB'] ) ); // => 1024MB - */ - formatSize: function( size, pointLength, units ) { - var unit; - - units = units || [ 'B', 'K', 'M', 'G', 'TB' ]; - - while ( (unit = units.shift()) && size > 1024 ) { - size = size / 1024; - } - - return (unit === 'B' ? size : size.toFixed( pointLength || 2 )) + - unit; - } - }; - }); - /** - * 浜嬩欢澶勭悊绫伙紝鍙互鐙珛浣跨敤锛屼篃鍙互鎵╁睍缁欏璞′娇鐢ㄣ�� - * @fileOverview Mediator - */ - define('mediator',[ - 'base' - ], function( Base ) { - var $ = Base.$, - slice = [].slice, - separator = /\s+/, - protos; - - // 鏍规嵁鏉′欢杩囨护鍑轰簨浠秇andlers. - function findHandlers( arr, name, callback, context ) { - return $.grep( arr, function( handler ) { - return handler && - (!name || handler.e === name) && - (!callback || handler.cb === callback || - handler.cb._cb === callback) && - (!context || handler.ctx === context); - }); - } - - function eachEvent( events, callback, iterator ) { - // 涓嶆敮鎸佸璞★紝鍙敮鎸佸涓猠vent鐢ㄧ┖鏍奸殧寮� - $.each( (events || '').split( separator ), function( _, key ) { - iterator( key, callback ); - }); - } - - function triggerHanders( events, args ) { - var stoped = false, - i = -1, - len = events.length, - handler; - - while ( ++i < len ) { - handler = events[ i ]; - - if ( handler.cb.apply( handler.ctx2, args ) === false ) { - stoped = true; - break; - } - } - - return !stoped; - } - - protos = { - - /** - * 缁戝畾浜嬩欢銆� - * - * `callback`鏂规硶鍦ㄦ墽琛屾椂锛宎rguments灏嗕細鏉ユ簮浜巘rigger鐨勬椂鍊欐惡甯︾殑鍙傛暟銆傚 - * ```javascript - * var obj = {}; - * - * // 浣垮緱obj鏈変簨浠惰涓� - * Mediator.installTo( obj ); - * - * obj.on( 'testa', function( arg1, arg2 ) { - * console.log( arg1, arg2 ); // => 'arg1', 'arg2' - * }); - * - * obj.trigger( 'testa', 'arg1', 'arg2' ); - * ``` - * - * 濡傛灉`callback`涓紝鏌愪竴涓柟娉昤return false`浜嗭紝鍒欏悗缁殑鍏朵粬`callback`閮戒笉浼氳鎵ц鍒般�� - * 鍒囦細褰卞搷鍒癭trigger`鏂规硶鐨勮繑鍥炲�硷紝涓篳false`銆� - * - * `on`杩樺彲浠ョ敤鏉ユ坊鍔犱竴涓壒娈婁簨浠禶all`, 杩欐牱鎵�鏈夌殑浜嬩欢瑙﹀彂閮戒細鍝嶅簲鍒般�傚悓鏃舵绫籤callback`涓殑arguments鏈変竴涓笉鍚屽锛� - * 灏辨槸绗竴涓弬鏁颁负`type`锛岃褰曞綋鍓嶆槸浠�涔堜簨浠跺湪瑙﹀彂銆傛绫籤callback`鐨勪紭鍏堢骇姣旇剼浣庯紝浼氬啀姝e父`callback`鎵ц瀹屽悗瑙﹀彂銆� - * ```javascript - * obj.on( 'all', function( type, arg1, arg2 ) { - * console.log( type, arg1, arg2 ); // => 'testa', 'arg1', 'arg2' - * }); - * ``` - * - * @method on - * @grammar on( name, callback[, context] ) => self - * @param {String} name 浜嬩欢鍚嶏紝鏀寔澶氫釜浜嬩欢鐢ㄧ┖鏍奸殧寮� - * @param {Function} callback 浜嬩欢澶勭悊鍣� - * @param {Object} [context] 浜嬩欢澶勭悊鍣ㄧ殑涓婁笅鏂囥�� - * @return {self} 杩斿洖鑷韩锛屾柟渚块摼寮� - * @chainable - * @class Mediator - */ - on: function( name, callback, context ) { - var me = this, - set; - - if ( !callback ) { - return this; - } - - set = this._events || (this._events = []); - - eachEvent( name, callback, function( name, callback ) { - var handler = { e: name }; - - handler.cb = callback; - handler.ctx = context; - handler.ctx2 = context || me; - handler.id = set.length; - - set.push( handler ); - }); - - return this; - }, - - /** - * 缁戝畾浜嬩欢锛屼笖褰揾andler鎵ц瀹屽悗锛岃嚜鍔ㄨВ闄ょ粦瀹氥�� - * @method once - * @grammar once( name, callback[, context] ) => self - * @param {String} name 浜嬩欢鍚� - * @param {Function} callback 浜嬩欢澶勭悊鍣� - * @param {Object} [context] 浜嬩欢澶勭悊鍣ㄧ殑涓婁笅鏂囥�� - * @return {self} 杩斿洖鑷韩锛屾柟渚块摼寮� - * @chainable - */ - once: function( name, callback, context ) { - var me = this; - - if ( !callback ) { - return me; - } - - eachEvent( name, callback, function( name, callback ) { - var once = function() { - me.off( name, once ); - return callback.apply( context || me, arguments ); - }; - - once._cb = callback; - me.on( name, once, context ); - }); - - return me; - }, - - /** - * 瑙i櫎浜嬩欢缁戝畾 - * @method off - * @grammar off( [name[, callback[, context] ] ] ) => self - * @param {String} [name] 浜嬩欢鍚� - * @param {Function} [callback] 浜嬩欢澶勭悊鍣� - * @param {Object} [context] 浜嬩欢澶勭悊鍣ㄧ殑涓婁笅鏂囥�� - * @return {self} 杩斿洖鑷韩锛屾柟渚块摼寮� - * @chainable - */ - off: function( name, cb, ctx ) { - var events = this._events; - - if ( !events ) { - return this; - } - - if ( !name && !cb && !ctx ) { - this._events = []; - return this; - } - - eachEvent( name, cb, function( name, cb ) { - $.each( findHandlers( events, name, cb, ctx ), function() { - delete events[ this.id ]; - }); - }); - - return this; - }, - - /** - * 瑙﹀彂浜嬩欢 - * @method trigger - * @grammar trigger( name[, args...] ) => self - * @param {String} type 浜嬩欢鍚� - * @param {*} [...] 浠绘剰鍙傛暟 - * @return {Boolean} 濡傛灉handler涓璻eturn false浜嗭紝鍒欒繑鍥瀎alse, 鍚﹀垯杩斿洖true - */ - trigger: function( type ) { - var args, events, allEvents; - - if ( !this._events || !type ) { - return this; - } - - args = slice.call( arguments, 1 ); - events = findHandlers( this._events, type ); - allEvents = findHandlers( this._events, 'all' ); - - return triggerHanders( events, args ) && - triggerHanders( allEvents, arguments ); - } - }; - - /** - * 涓粙鑰咃紝瀹冩湰韬槸涓崟渚嬶紝浣嗗彲浠ラ�氳繃[installTo](#WebUploader:Mediator:installTo)鏂规硶锛屼娇浠讳綍瀵硅薄鍏峰浜嬩欢琛屼负銆� - * 涓昏鐩殑鏄礋璐fā鍧椾笌妯″潡涔嬮棿鐨勫悎浣滐紝闄嶄綆鑰﹀悎搴︺�� - * - * @class Mediator - */ - return $.extend({ - - /** - * 鍙互閫氳繃杩欎釜鎺ュ彛锛屼娇浠讳綍瀵硅薄鍏峰浜嬩欢鍔熻兘銆� - * @method installTo - * @param {Object} obj 闇�瑕佸叿澶囦簨浠惰涓虹殑瀵硅薄銆� - * @return {Object} 杩斿洖obj. - */ - installTo: function( obj ) { - return $.extend( obj, protos ); - } - - }, protos ); - }); - /** - * @fileOverview Uploader涓婁紶绫� - */ - define('uploader',[ - 'base', - 'mediator' - ], function( Base, Mediator ) { - - var $ = Base.$; - - /** - * 涓婁紶鍏ュ彛绫汇�� - * @class Uploader - * @constructor - * @grammar new Uploader( opts ) => Uploader - * @example - * var uploader = WebUploader.Uploader({ - * swf: 'path_of_swf/Uploader.swf', - * - * // 寮�璧峰垎鐗囦笂浼犮�� - * chunked: true - * }); - */ - function Uploader( opts ) { - this.options = $.extend( true, {}, Uploader.options, opts ); - this._init( this.options ); - } - - // default Options - // widgets涓湁鐩稿簲鎵╁睍 - Uploader.options = {}; - Mediator.installTo( Uploader.prototype ); - - // 鎵归噺娣诲姞绾懡浠ゅ紡鏂规硶銆� - $.each({ - upload: 'start-upload', - stop: 'stop-upload', - getFile: 'get-file', - getFiles: 'get-files', - addFile: 'add-file', - addFiles: 'add-file', - sort: 'sort-files', - removeFile: 'remove-file', - skipFile: 'skip-file', - retry: 'retry', - isInProgress: 'is-in-progress', - makeThumb: 'make-thumb', - getDimension: 'get-dimension', - addButton: 'add-btn', - getRuntimeType: 'get-runtime-type', - refresh: 'refresh', - disable: 'disable', - enable: 'enable', - reset: 'reset' - }, function( fn, command ) { - Uploader.prototype[ fn ] = function() { - return this.request( command, arguments ); - }; - }); - - $.extend( Uploader.prototype, { - state: 'pending', - - _init: function( opts ) { - var me = this; - - me.request( 'init', opts, function() { - me.state = 'ready'; - me.trigger('ready'); - }); - }, - - /** - * 鑾峰彇鎴栬�呰缃甎ploader閰嶇疆椤广�� - * @method option - * @grammar option( key ) => * - * @grammar option( key, val ) => self - * @example - * - * // 鍒濆鐘舵�佸浘鐗囦笂浼犲墠涓嶄細鍘嬬缉 - * var uploader = new WebUploader.Uploader({ - * resize: null; - * }); - * - * // 淇敼鍚庡浘鐗囦笂浼犲墠锛屽皾璇曞皢鍥剧墖鍘嬬缉鍒�1600 * 1600 - * uploader.options( 'resize', { - * width: 1600, - * height: 1600 - * }); - */ - option: function( key, val ) { - var opts = this.options; - - // setter - if ( arguments.length > 1 ) { - - if ( $.isPlainObject( val ) && - $.isPlainObject( opts[ key ] ) ) { - $.extend( opts[ key ], val ); - } else { - opts[ key ] = val; - } - - } else { // getter - return key ? opts[ key ] : opts; - } - }, - - /** - * 鑾峰彇鏂囦欢缁熻淇℃伅銆傝繑鍥炰竴涓寘鍚竴涓嬩俊鎭殑瀵硅薄銆� - * * `successNum` 涓婁紶鎴愬姛鐨勬枃浠舵暟 - * * `uploadFailNum` 涓婁紶澶辫触鐨勬枃浠舵暟 - * * `cancelNum` 琚垹闄ょ殑鏂囦欢鏁� - * * `invalidNum` 鏃犳晥鐨勬枃浠舵暟 - * * `queueNum` 杩樺湪闃熷垪涓殑鏂囦欢鏁� - * @method getStats - * @grammar getStats() => Object - */ - getStats: function() { - // return this._mgr.getStats.apply( this._mgr, arguments ); - var stats = this.request('get-stats'); - - return { - successNum: stats.numOfSuccess, - - // who care? - // queueFailNum: 0, - cancelNum: stats.numOfCancel, - invalidNum: stats.numOfInvalid, - uploadFailNum: stats.numOfUploadFailed, - queueNum: stats.numOfQueue - }; - }, - - // 闇�瑕侀噸鍐欐鏂规硶鏉ユ潵鏀寔opts.onEvent鍜宨nstance.onEvent鐨勫鐞嗗櫒 - trigger: function( type/*, args...*/ ) { - var args = [].slice.call( arguments, 1 ), - opts = this.options, - name = 'on' + type.substring( 0, 1 ).toUpperCase() + - type.substring( 1 ); - - if ( - // 璋冪敤閫氳繃on鏂规硶娉ㄥ唽鐨刪andler. - Mediator.trigger.apply( this, arguments ) === false || - - // 璋冪敤opts.onEvent - $.isFunction( opts[ name ] ) && - opts[ name ].apply( this, args ) === false || - - // 璋冪敤this.onEvent - $.isFunction( this[ name ] ) && - this[ name ].apply( this, args ) === false || - - // 骞挎挱鎵�鏈塽ploader鐨勪簨浠躲�� - Mediator.trigger.apply( Mediator, - [ this, type ].concat( args ) ) === false ) { - - return false; - } - - return true; - }, - - // widgets/widget.js灏嗚ˉ鍏呮鏂规硶鐨勮缁嗘枃妗c�� - request: Base.noop - }); - - /** - * 鍒涘缓Uploader瀹炰緥锛岀瓑鍚屼簬new Uploader( opts ); - * @method create - * @class Base - * @static - * @grammar Base.create( opts ) => Uploader - */ - Base.create = Uploader.create = function( opts ) { - return new Uploader( opts ); - }; - - // 鏆撮湶Uploader锛屽彲浠ラ�氳繃瀹冩潵鎵╁睍涓氬姟閫昏緫銆� - Base.Uploader = Uploader; - - return Uploader; - }); - /** - * @fileOverview Runtime绠$悊鍣紝璐熻矗Runtime鐨勯�夋嫨, 杩炴帴 - */ - define('runtime/runtime',[ - 'base', - 'mediator' - ], function( Base, Mediator ) { - - var $ = Base.$, - factories = {}, - - // 鑾峰彇瀵硅薄鐨勭涓�涓猭ey - getFirstKey = function( obj ) { - for ( var key in obj ) { - if ( obj.hasOwnProperty( key ) ) { - return key; - } - } - return null; - }; - - // 鎺ュ彛绫汇�� - function Runtime( options ) { - this.options = $.extend({ - container: document.body - }, options ); - this.uid = Base.guid('rt_'); - } - - $.extend( Runtime.prototype, { - - getContainer: function() { - var opts = this.options, - parent, container; - - if ( this._container ) { - return this._container; - } - - parent = $( opts.container || document.body ); - container = $( document.createElement('div') ); - - container.attr( 'id', 'rt_' + this.uid ); - container.css({ - position: 'absolute', - top: '0px', - left: '0px', - width: '1px', - height: '1px', - overflow: 'hidden' - }); - - parent.append( container ); - parent.addClass('webuploader-container'); - this._container = container; - return container; - }, - - init: Base.noop, - exec: Base.noop, - - destroy: function() { - if ( this._container ) { - this._container.parentNode.removeChild( this.__container ); - } - - this.off(); - } - }); - - Runtime.orders = 'html5,flash'; - - - /** - * 娣诲姞Runtime瀹炵幇銆� - * @param {String} type 绫诲瀷 - * @param {Runtime} factory 鍏蜂綋Runtime瀹炵幇銆� - */ - Runtime.addRuntime = function( type, factory ) { - factories[ type ] = factory; - }; - - Runtime.hasRuntime = function( type ) { - return !!(type ? factories[ type ] : getFirstKey( factories )); - }; - - Runtime.create = function( opts, orders ) { - var type, runtime; - - orders = orders || Runtime.orders; - $.each( orders.split( /\s*,\s*/g ), function() { - if ( factories[ this ] ) { - type = this; - return false; - } - }); - - type = type || getFirstKey( factories ); - - if ( !type ) { - throw new Error('Runtime Error'); - } - - runtime = new factories[ type ]( opts ); - return runtime; - }; - - Mediator.installTo( Runtime.prototype ); - return Runtime; - }); - - /** - * @fileOverview Runtime绠$悊鍣紝璐熻矗Runtime鐨勯�夋嫨, 杩炴帴 - */ - define('runtime/client',[ - 'base', - 'mediator', - 'runtime/runtime' - ], function( Base, Mediator, Runtime ) { - - var cache; - - cache = (function() { - var obj = {}; - - return { - add: function( runtime ) { - obj[ runtime.uid ] = runtime; - }, - - get: function( ruid, standalone ) { - var i; - - if ( ruid ) { - return obj[ ruid ]; - } - - for ( i in obj ) { - // 鏈変簺绫诲瀷涓嶈兘閲嶇敤锛屾瘮濡俧ilepicker. - if ( standalone && obj[ i ].__standalone ) { - continue; - } - - return obj[ i ]; - } - - return null; - }, - - remove: function( runtime ) { - delete obj[ runtime.uid ]; - } - }; - })(); - - function RuntimeClient( component, standalone ) { - var deferred = Base.Deferred(), - runtime; - - this.uid = Base.guid('client_'); - - // 鍏佽runtime娌℃湁鍒濆鍖栦箣鍓嶏紝娉ㄥ唽涓�浜涙柟娉曞湪鍒濆鍖栧悗鎵ц銆� - this.runtimeReady = function( cb ) { - return deferred.done( cb ); - }; - - this.connectRuntime = function( opts, cb ) { - - // already connected. - if ( runtime ) { - throw new Error('already connected!'); - } - - deferred.done( cb ); - - if ( typeof opts === 'string' && cache.get( opts ) ) { - runtime = cache.get( opts ); - } - - // 鍍廸ilePicker鍙兘鐙珛瀛樺湪锛屼笉鑳藉叕鐢ㄣ�� - runtime = runtime || cache.get( null, standalone ); - - // 闇�瑕佸垱寤� - if ( !runtime ) { - runtime = Runtime.create( opts, opts.runtimeOrder ); - runtime.__promise = deferred.promise(); - runtime.once( 'ready', deferred.resolve ); - runtime.init(); - cache.add( runtime ); - runtime.__client = 1; - } else { - // 鏉ヨ嚜cache - Base.$.extend( runtime.options, opts ); - runtime.__promise.then( deferred.resolve ); - runtime.__client++; - } - - standalone && (runtime.__standalone = standalone); - return runtime; - }; - - this.getRuntime = function() { - return runtime; - }; - - this.disconnectRuntime = function() { - if ( !runtime ) { - return; - } - - runtime.__client--; - - if ( runtime.__client <= 0 ) { - cache.remove( runtime ); - delete runtime.__promise; - runtime.destroy(); - } - - runtime = null; - }; - - this.exec = function() { - if ( !runtime ) { - return; - } - - var args = Base.slice( arguments ); - component && args.unshift( component ); - - return runtime.exec.apply( this, args ); - }; - - this.getRuid = function() { - return runtime && runtime.uid; - }; - - this.destroy = (function( destroy ) { - return function() { - destroy && destroy.apply( this, arguments ); - this.trigger('destroy'); - this.off(); - this.exec('destroy'); - this.disconnectRuntime(); - }; - })( this.destroy ); - } - - Mediator.installTo( RuntimeClient.prototype ); - return RuntimeClient; - }); - /** - * @fileOverview 閿欒淇℃伅 - */ - define('lib/dnd',[ - 'base', - 'mediator', - 'runtime/client' - ], function( Base, Mediator, RuntimeClent ) { - - var $ = Base.$; - - function DragAndDrop( opts ) { - opts = this.options = $.extend({}, DragAndDrop.options, opts ); - - opts.container = $( opts.container ); - - if ( !opts.container.length ) { - return; - } - - RuntimeClent.call( this, 'DragAndDrop' ); - } - - DragAndDrop.options = { - accept: null, - disableGlobalDnd: false - }; - - Base.inherits( RuntimeClent, { - constructor: DragAndDrop, - - init: function() { - var me = this; - - me.connectRuntime( me.options, function() { - me.exec('init'); - me.trigger('ready'); - }); - }, - - destroy: function() { - this.disconnectRuntime(); - } - }); - - Mediator.installTo( DragAndDrop.prototype ); - - return DragAndDrop; - }); - /** - * @fileOverview 缁勪欢鍩虹被銆� - */ - define('widgets/widget',[ - 'base', - 'uploader' - ], function( Base, Uploader ) { - - var $ = Base.$, - _init = Uploader.prototype._init, - IGNORE = {}, - widgetClass = []; - - function isArrayLike( obj ) { - if ( !obj ) { - return false; - } - - var length = obj.length, - type = $.type( obj ); - - if ( obj.nodeType === 1 && length ) { - return true; - } - - return type === 'array' || type !== 'function' && type !== 'string' && - (length === 0 || typeof length === 'number' && length > 0 && - (length - 1) in obj); - } - - function Widget( uploader ) { - this.owner = uploader; - this.options = uploader.options; - } - - $.extend( Widget.prototype, { - - init: Base.noop, - - // 绫籅ackbone鐨勪簨浠剁洃鍚0鏄庯紝鐩戝惉uploader瀹炰緥涓婄殑浜嬩欢 - // widget鐩存帴鏃犳硶鐩戝惉浜嬩欢锛屼簨浠跺彧鑳介�氳繃uploader鏉ヤ紶閫� - invoke: function( apiName, args ) { - - /* - { - 'make-thumb': 'makeThumb' - } - */ - var map = this.responseMap; - - // 濡傛灉鏃燗PI鍝嶅簲澹版槑鍒欏拷鐣� - if ( !map || !(apiName in map) || !(map[ apiName ] in this) || - !$.isFunction( this[ map[ apiName ] ] ) ) { - - return IGNORE; - } - - return this[ map[ apiName ] ].apply( this, args ); - - }, - - /** - * 鍙戦�佸懡浠ゃ�傚綋浼犲叆`callback`鎴栬�卄handler`涓繑鍥瀈promise`鏃躲�傝繑鍥炰竴涓綋鎵�鏈塦handler`涓殑promise閮藉畬鎴愬悗瀹屾垚鐨勬柊`promise`銆� - * @method request - * @grammar request( command, args ) => * | Promise - * @grammar request( command, args, callback ) => Promise - * @for Uploader - */ - request: function() { - return this.owner.request.apply( this.owner, arguments ); - } - }); - - // 鎵╁睍Uploader. - $.extend( Uploader.prototype, { - - // 瑕嗗啓_init鐢ㄦ潵鍒濆鍖杦idgets - _init: function() { - var me = this, - widgets = me._widgets = []; - - $.each( widgetClass, function( _, klass ) { - widgets.push( new klass( me ) ); - }); - - return _init.apply( me, arguments ); - }, - - request: function( apiName, args, callback ) { - var i = 0, - widgets = this._widgets, - len = widgets.length, - rlts = [], - dfds = [], - widget, rlt, promise, key; - - args = isArrayLike( args ) ? args : [ args ]; - - for ( ; i < len; i++ ) { - widget = widgets[ i ]; - rlt = widget.invoke( apiName, args ); - - if ( rlt !== IGNORE ) { - - // Deferred瀵硅薄 - if ( Base.isPromise( rlt ) ) { - dfds.push( rlt ); - } else { - rlts.push( rlt ); - } - } - } - - // 濡傛灉鏈塩allback锛屽垯鐢ㄥ紓姝ユ柟寮忋�� - if ( callback || dfds.length ) { - promise = Base.when.apply( Base, dfds ); - key = promise.pipe ? 'pipe' : 'then'; - - // 寰堥噸瑕佷笉鑳藉垹闄ゃ�傚垹闄や簡浼氭寰幆銆� - // 淇濊瘉鎵ц椤哄簭銆傝callback鎬绘槸鍦ㄤ笅涓�涓猼ick涓墽琛屻�� - return promise[ key ](function() { - var deferred = Base.Deferred(), - args = arguments; - - setTimeout(function() { - deferred.resolve.apply( deferred, args ); - }, 1 ); - - return deferred.promise(); - })[ key ]( callback || Base.noop ); - } else { - return rlts[ 0 ]; - } - } - }); - - /** - * 娣诲姞缁勪欢 - * @param {object} widgetProto 缁勪欢鍘熷瀷锛屾瀯閫犲嚱鏁伴�氳繃constructor灞炴�у畾涔� - * @param {object} responseMap API鍚嶇О涓庡嚱鏁板疄鐜扮殑鏄犲皠 - * @example - * Uploader.register( { - * init: function( options ) {}, - * makeThumb: function() {} - * }, { - * 'make-thumb': 'makeThumb' - * } ); - */ - Uploader.register = Widget.register = function( responseMap, widgetProto ) { - var map = { init: 'init' }, - klass; - - if ( arguments.length === 1 ) { - widgetProto = responseMap; - widgetProto.responseMap = map; - } else { - widgetProto.responseMap = $.extend( map, responseMap ); - } - - klass = Base.inherits( Widget, widgetProto ); - widgetClass.push( klass ); - - return klass; - }; - - return Widget; - }); - /** - * @fileOverview DragAndDrop Widget銆� - */ - define('widgets/filednd',[ - 'base', - 'uploader', - 'lib/dnd', - 'widgets/widget' - ], function( Base, Uploader, Dnd ) { - var $ = Base.$; - - Uploader.options.dnd = ''; - - /** - * @property {Selector} [dnd=undefined] 鎸囧畾Drag And Drop鎷栨嫿鐨勫鍣紝濡傛灉涓嶆寚瀹氾紝鍒欎笉鍚姩銆� - * @namespace options - * @for Uploader - */ - - /** - * @event dndAccept - * @param {DataTransferItemList} items DataTransferItem - * @description 闃绘姝や簨浠跺彲浠ユ嫆缁濇煇浜涚被鍨嬬殑鏂囦欢鎷栧叆杩涙潵銆傜洰鍓嶅彧鏈� chrome 鎻愪緵杩欐牱鐨� API锛屼笖鍙兘閫氳繃 mime-type 楠岃瘉銆� - * @for Uploader - */ - return Uploader.register({ - init: function( opts ) { - - if ( !opts.dnd || - this.request('predict-runtime-type') !== 'html5' ) { - return; - } - - var me = this, - deferred = Base.Deferred(), - options = $.extend({}, { - disableGlobalDnd: opts.disableGlobalDnd, - container: opts.dnd, - accept: opts.accept - }), - dnd; - - dnd = new Dnd( options ); - - dnd.once( 'ready', deferred.resolve ); - dnd.on( 'drop', function( files ) { - me.request( 'add-file', [ files ]); - }); - - // 妫�娴嬫枃浠舵槸鍚﹀叏閮ㄥ厑璁告坊鍔犮�� - dnd.on( 'accept', function( items ) { - return me.owner.trigger( 'dndAccept', items ); - }); - - dnd.init(); - - return deferred.promise(); - } - }); - }); - - /** - * @fileOverview 閿欒淇℃伅 - */ - define('lib/filepaste',[ - 'base', - 'mediator', - 'runtime/client' - ], function( Base, Mediator, RuntimeClent ) { - - var $ = Base.$; - - function FilePaste( opts ) { - opts = this.options = $.extend({}, opts ); - opts.container = $( opts.container || document.body ); - RuntimeClent.call( this, 'FilePaste' ); - } - - Base.inherits( RuntimeClent, { - constructor: FilePaste, - - init: function() { - var me = this; - - me.connectRuntime( me.options, function() { - me.exec('init'); - me.trigger('ready'); - }); - }, - - destroy: function() { - this.exec('destroy'); - this.disconnectRuntime(); - this.off(); - } - }); - - Mediator.installTo( FilePaste.prototype ); - - return FilePaste; - }); - /** - * @fileOverview 缁勪欢鍩虹被銆� - */ - define('widgets/filepaste',[ - 'base', - 'uploader', - 'lib/filepaste', - 'widgets/widget' - ], function( Base, Uploader, FilePaste ) { - var $ = Base.$; - - /** - * @property {Selector} [paste=undefined] 鎸囧畾鐩戝惉paste浜嬩欢鐨勫鍣紝濡傛灉涓嶆寚瀹氾紝涓嶅惎鐢ㄦ鍔熻兘銆傛鍔熻兘涓洪�氳繃绮樿创鏉ユ坊鍔犳埅灞忕殑鍥剧墖銆傚缓璁缃负`document.body`. - * @namespace options - * @for Uploader - */ - return Uploader.register({ - init: function( opts ) { - - if ( !opts.paste || - this.request('predict-runtime-type') !== 'html5' ) { - return; - } - - var me = this, - deferred = Base.Deferred(), - options = $.extend({}, { - container: opts.paste, - accept: opts.accept - }), - paste; - - paste = new FilePaste( options ); - - paste.once( 'ready', deferred.resolve ); - paste.on( 'paste', function( files ) { - me.owner.request( 'add-file', [ files ]); - }); - paste.init(); - - return deferred.promise(); - } - }); - }); - /** - * @fileOverview Blob - */ - define('lib/blob',[ - 'base', - 'runtime/client' - ], function( Base, RuntimeClient ) { - - function Blob( ruid, source ) { - var me = this; - - me.source = source; - me.ruid = ruid; - - RuntimeClient.call( me, 'Blob' ); - - this.uid = source.uid || this.uid; - this.type = source.type || ''; - this.size = source.size || 0; - - if ( ruid ) { - me.connectRuntime( ruid ); - } - } - - Base.inherits( RuntimeClient, { - constructor: Blob, - - slice: function( start, end ) { - return this.exec( 'slice', start, end ); - }, - - getSource: function() { - return this.source; - } - }); - - return Blob; - }); - /** - * 涓轰簡缁熶竴鍖朏lash鐨凢ile鍜孒TML5鐨凢ile鑰屽瓨鍦ㄣ�� - * 浠ヨ嚦浜庤璋冪敤Flash閲岄潰鐨凢ile锛屼篃鍙互鍍忚皟鐢℉TML5鐗堟湰鐨凢ile涓�涓嬨�� - * @fileOverview File - */ - define('lib/file',[ - 'base', - 'lib/blob' - ], function( Base, Blob ) { - - var uid = 1, - rExt = /\.([^.]+)$/; - - function File( ruid, file ) { - var ext; - - Blob.apply( this, arguments ); - this.name = file.name || ('untitled' + uid++); - ext = rExt.exec( file.name ) ? RegExp.$1.toLowerCase() : ''; - - // todo 鏀寔鍏朵粬绫诲瀷鏂囦欢鐨勮浆鎹€�� - - // 濡傛灉鏈塵imetype, 浣嗘槸鏂囦欢鍚嶉噷闈㈡病鏈夋壘鍑哄悗缂�瑙勫緥 - if ( !ext && this.type ) { - ext = /\/(jpg|jpeg|png|gif|bmp)$/i.exec( this.type ) ? - RegExp.$1.toLowerCase() : ''; - this.name += '.' + ext; - } - - // 濡傛灉娌℃湁鎸囧畾mimetype, 浣嗘槸鐭ラ亾鏂囦欢鍚庣紑銆� - if ( !this.type && ~'jpg,jpeg,png,gif,bmp'.indexOf( ext ) ) { - this.type = 'image/' + (ext === 'jpg' ? 'jpeg' : ext); - } - - this.ext = ext; - this.lastModifiedDate = file.lastModifiedDate || - (new Date()).toLocaleString(); - } - - return Base.inherits( Blob, File ); - }); - - /** - * @fileOverview 閿欒淇℃伅 - */ - define('lib/filepicker',[ - 'base', - 'runtime/client', - 'lib/file' - ], function( Base, RuntimeClent, File ) { - - var $ = Base.$; - - function FilePicker( opts ) { - opts = this.options = $.extend({}, FilePicker.options, opts ); - - opts.container = $( opts.id ); - - if ( !opts.container.length ) { - throw new Error('鎸夐挳鎸囧畾閿欒'); - } - - opts.innerHTML = opts.innerHTML || opts.label || - opts.container.html() || ''; - - opts.button = $( opts.button || document.createElement('div') ); - opts.button.html( opts.innerHTML ); - opts.container.html( opts.button ); - - RuntimeClent.call( this, 'FilePicker', true ); - } - - FilePicker.options = { - button: null, - container: null, - label: null, - innerHTML: null, - multiple: true, - accept: null, - name: 'file' - }; - - Base.inherits( RuntimeClent, { - constructor: FilePicker, - - init: function() { - var me = this, - opts = me.options, - button = opts.button; - - button.addClass('webuploader-pick'); - - me.on( 'all', function( type ) { - var files; - - switch ( type ) { - case 'mouseenter': - button.addClass('webuploader-pick-hover'); - break; - - case 'mouseleave': - button.removeClass('webuploader-pick-hover'); - break; - - case 'change': - files = me.exec('getFiles'); - me.trigger( 'select', $.map( files, function( file ) { - file = new File( me.getRuid(), file ); - - // 璁板綍鏉ユ簮銆� - file._refer = opts.container; - return file; - }), opts.container ); - break; - } - }); - - me.connectRuntime( opts, function() { - me.refresh(); - me.exec( 'init', opts ); - me.trigger('ready'); - }); - - $( window ).on( 'resize', function() { - me.refresh(); - }); - }, - - refresh: function() { - var shimContainer = this.getRuntime().getContainer(), - button = this.options.button, - width = button.outerWidth ? - button.outerWidth() : button.width(), - - height = button.outerHeight ? - button.outerHeight() : button.height(), - - pos = button.offset(); - - width && height && shimContainer.css({ - bottom: 'auto', - right: 'auto', - width: width + 'px', - height: height + 'px' - }).offset( pos ); - }, - - enable: function() { - var btn = this.options.button; - - btn.removeClass('webuploader-pick-disable'); - this.refresh(); - }, - - disable: function() { - var btn = this.options.button; - - this.getRuntime().getContainer().css({ - top: '-99999px' - }); - - btn.addClass('webuploader-pick-disable'); - }, - - destroy: function() { - if ( this.runtime ) { - this.exec('destroy'); - this.disconnectRuntime(); - } - } - }); - - return FilePicker; - }); - - /** - * @fileOverview 鏂囦欢閫夋嫨鐩稿叧 - */ - define('widgets/filepicker',[ - 'base', - 'uploader', - 'lib/filepicker', - 'widgets/widget' - ], function( Base, Uploader, FilePicker ) { - var $ = Base.$; - - $.extend( Uploader.options, { - - /** - * @property {Selector | Object} [pick=undefined] - * @namespace options - * @for Uploader - * @description 鎸囧畾閫夋嫨鏂囦欢鐨勬寜閽鍣紝涓嶆寚瀹氬垯涓嶅垱寤烘寜閽�� - * - * * `id` {Seletor} 鎸囧畾閫夋嫨鏂囦欢鐨勬寜閽鍣紝涓嶆寚瀹氬垯涓嶅垱寤烘寜閽�� - * * `label` {String} 璇烽噰鐢� `innerHTML` 浠f浛 - * * `innerHTML` {String} 鎸囧畾鎸夐挳鏂囧瓧銆備笉鎸囧畾鏃朵紭鍏堜粠鎸囧畾鐨勫鍣ㄤ腑鐪嬫槸鍚﹁嚜甯︽枃瀛椼�� - * * `multiple` {Boolean} 鏄惁寮�璧峰悓鏃堕�夋嫨澶氫釜鏂囦欢鑳藉姏銆� - */ - pick: null, - - /** - * @property {Arroy} [accept=null] - * @namespace options - * @for Uploader - * @description 鎸囧畾鎺ュ彈鍝簺绫诲瀷鐨勬枃浠躲�� 鐢变簬鐩墠杩樻湁ext杞琺imeType琛紝鎵�浠ヨ繖閲岄渶瑕佸垎寮�鎸囧畾銆� - * - * * `title` {String} 鏂囧瓧鎻忚堪 - * * `extensions` {String} 鍏佽鐨勬枃浠跺悗缂�锛屼笉甯︾偣锛屽涓敤閫楀彿鍒嗗壊銆� - * * `mimeTypes` {String} 澶氫釜鐢ㄩ�楀彿鍒嗗壊銆� - * - * 濡傦細 - * - * ``` - * { - * title: 'Images', - * extensions: 'gif,jpg,jpeg,bmp,png', - * mimeTypes: 'image/*' - * } - * ``` - */ - accept: null/*{ - title: 'Images', - extensions: 'gif,jpg,jpeg,bmp,png', - mimeTypes: 'image/*' - }*/ - }); - - return Uploader.register({ - 'add-btn': 'addButton', - refresh: 'refresh', - disable: 'disable', - enable: 'enable' - }, { - - init: function( opts ) { - this.pickers = []; - return opts.pick && this.addButton( opts.pick ); - }, - - refresh: function() { - $.each( this.pickers, function() { - this.refresh(); - }); - }, - - /** - * @method addButton - * @for Uploader - * @grammar addButton( pick ) => Promise - * @description - * 娣诲姞鏂囦欢閫夋嫨鎸夐挳锛屽鏋滀竴涓寜閽笉澶燂紝闇�瑕佽皟鐢ㄦ鏂规硶鏉ユ坊鍔犮�傚弬鏁拌窡[options.pick](#WebUploader:Uploader:options)涓�鑷淬�� - * @example - * uploader.addButton({ - * id: '#btnContainer', - * innerHTML: '閫夋嫨鏂囦欢' - * }); - */ - addButton: function( pick ) { - var me = this, - opts = me.options, - accept = opts.accept, - options, picker, deferred; - - if ( !pick ) { - return; - } - - deferred = Base.Deferred(); - $.isPlainObject( pick ) || (pick = { - id: pick - }); - - options = $.extend({}, pick, { - accept: $.isPlainObject( accept ) ? [ accept ] : accept, - swf: opts.swf, - runtimeOrder: opts.runtimeOrder - }); - - picker = new FilePicker( options ); - - picker.once( 'ready', deferred.resolve ); - picker.on( 'select', function( files ) { - me.owner.request( 'add-file', [ files ]); - }); - picker.init(); - - this.pickers.push( picker ); - - return deferred.promise(); - }, - - disable: function() { - $.each( this.pickers, function() { - this.disable(); - }); - }, - - enable: function() { - $.each( this.pickers, function() { - this.enable(); - }); - } - }); - }); - /** - * @fileOverview Image - */ - define('lib/image',[ - 'base', - 'runtime/client', - 'lib/blob' - ], function( Base, RuntimeClient, Blob ) { - var $ = Base.$; - - // 鏋勯�犲櫒銆� - function Image( opts ) { - this.options = $.extend({}, Image.options, opts ); - RuntimeClient.call( this, 'Image' ); - - this.on( 'load', function() { - this._info = this.exec('info'); - this._meta = this.exec('meta'); - }); - } - - // 榛樿閫夐」銆� - Image.options = { - - // 榛樿鐨勫浘鐗囧鐞嗚川閲� - quality: 90, - - // 鏄惁瑁佸壀 - crop: false, - - // 鏄惁淇濈暀澶撮儴淇℃伅 - preserveHeaders: true, - - // 鏄惁鍏佽鏀惧ぇ銆� - allowMagnify: true - }; - - // 缁ф壙RuntimeClient. - Base.inherits( RuntimeClient, { - constructor: Image, - - info: function( val ) { - - // setter - if ( val ) { - this._info = val; - return this; - } - - // getter - return this._info; - }, - - meta: function( val ) { - - // setter - if ( val ) { - this._meta = val; - return this; - } - - // getter - return this._meta; - }, - - loadFromBlob: function( blob ) { - var me = this, - ruid = blob.getRuid(); - - this.connectRuntime( ruid, function() { - me.exec( 'init', me.options ); - me.exec( 'loadFromBlob', blob ); - }); - }, - - resize: function() { - var args = Base.slice( arguments ); - return this.exec.apply( this, [ 'resize' ].concat( args ) ); - }, - - getAsDataUrl: function( type ) { - return this.exec( 'getAsDataUrl', type ); - }, - - getAsBlob: function( type ) { - var blob = this.exec( 'getAsBlob', type ); - - return new Blob( this.getRuid(), blob ); - } - }); - - return Image; - }); - /** - * @fileOverview 鍥剧墖鎿嶄綔, 璐熻矗棰勮鍥剧墖鍜屼笂浼犲墠鍘嬬缉鍥剧墖 - */ - define('widgets/image',[ - 'base', - 'uploader', - 'lib/image', - 'widgets/widget' - ], function( Base, Uploader, Image ) { - - var $ = Base.$, - throttle; - - // 鏍规嵁瑕佸鐞嗙殑鏂囦欢澶у皬鏉ヨ妭娴侊紝涓�娆′笉鑳藉鐞嗗お澶氾紝浼氬崱銆� - throttle = (function( max ) { - var occupied = 0, - waiting = [], - tick = function() { - var item; - - while ( waiting.length && occupied < max ) { - item = waiting.shift(); - occupied += item[ 0 ]; - item[ 1 ](); - } - }; - - return function( emiter, size, cb ) { - waiting.push([ size, cb ]); - emiter.once( 'destroy', function() { - occupied -= size; - setTimeout( tick, 1 ); - }); - setTimeout( tick, 1 ); - }; - })( 5 * 1024 * 1024 ); - - $.extend( Uploader.options, { - - /** - * @property {Object} [thumb] - * @namespace options - * @for Uploader - * @description 閰嶇疆鐢熸垚缂╃暐鍥剧殑閫夐」銆� - * - * 榛樿涓猴細 - * - * ```javascript - * { - * width: 110, - * height: 110, - * - * // 鍥剧墖璐ㄩ噺锛屽彧鏈塼ype涓篳image/jpeg`鐨勬椂鍊欐墠鏈夋晥銆� - * quality: 70, - * - * // 鏄惁鍏佽鏀惧ぇ锛屽鏋滄兂瑕佺敓鎴愬皬鍥剧殑鏃跺�欎笉澶辩湡锛屾閫夐」搴旇璁剧疆涓篺alse. - * allowMagnify: true, - * - * // 鏄惁鍏佽瑁佸壀銆� - * crop: true, - * - * // 鏄惁淇濈暀澶撮儴meta淇℃伅銆� - * preserveHeaders: false, - * - * // 涓虹┖鐨勮瘽鍒欎繚鐣欏師鏈夊浘鐗囨牸寮忋�� - * // 鍚﹀垯寮哄埗杞崲鎴愭寚瀹氱殑绫诲瀷銆� - * type: 'image/jpeg' - * } - * ``` - */ - thumb: { - width: 110, - height: 110, - quality: 70, - allowMagnify: true, - crop: true, - preserveHeaders: false, - - // 涓虹┖鐨勮瘽鍒欎繚鐣欏師鏈夊浘鐗囨牸寮忋�� - // 鍚﹀垯寮哄埗杞崲鎴愭寚瀹氱殑绫诲瀷銆� - // IE 8涓嬮潰 base64 澶у皬涓嶈兘瓒呰繃 32K 鍚﹀垯棰勮澶辫触锛岃�岄潪 jpeg 缂栫爜鐨勫浘鐗囧緢鍙� - // 鑳戒細瓒呰繃 32k, 鎵�浠ヨ繖閲岃缃垚棰勮鐨勬椂鍊欓兘鏄� image/jpeg - type: 'image/jpeg' - }, - - /** - * @property {Object} [compress] - * @namespace options - * @for Uploader - * @description 閰嶇疆鍘嬬缉鐨勫浘鐗囩殑閫夐」銆傚鏋滄閫夐」涓篳false`, 鍒欏浘鐗囧湪涓婁紶鍓嶄笉杩涜鍘嬬缉銆� - * - * 榛樿涓猴細 - * - * ```javascript - * { - * width: 1600, - * height: 1600, - * - * // 鍥剧墖璐ㄩ噺锛屽彧鏈塼ype涓篳image/jpeg`鐨勬椂鍊欐墠鏈夋晥銆� - * quality: 90, - * - * // 鏄惁鍏佽鏀惧ぇ锛屽鏋滄兂瑕佺敓鎴愬皬鍥剧殑鏃跺�欎笉澶辩湡锛屾閫夐」搴旇璁剧疆涓篺alse. - * allowMagnify: false, - * - * // 鏄惁鍏佽瑁佸壀銆� - * crop: false, - * - * // 鏄惁淇濈暀澶撮儴meta淇℃伅銆� - * preserveHeaders: true - * } - * ``` - */ - compress: { - width: 1600, - height: 1600, - quality: 90, - allowMagnify: false, - crop: false, - preserveHeaders: true - } - }); - - return Uploader.register({ - 'make-thumb': 'makeThumb', - 'before-send-file': 'compressImage' - }, { - - - /** - * 鐢熸垚缂╃暐鍥撅紝姝よ繃绋嬩负寮傛锛屾墍浠ラ渶瑕佷紶鍏callback`銆� - * 閫氬父鎯呭喌鍦ㄥ浘鐗囧姞鍏ラ槦閲屽悗璋冪敤姝ゆ柟娉曟潵鐢熸垚棰勮鍥句互澧炲己浜や簰鏁堟灉銆� - * - * `callback`涓彲浠ユ帴鏀跺埌涓や釜鍙傛暟銆� - * * 绗竴涓负error锛屽鏋滅敓鎴愮缉鐣ュ浘鏈夐敊璇紝姝rror灏嗕负鐪熴�� - * * 绗簩涓负ret, 缂╃暐鍥剧殑Data URL鍊笺�� - * - * **娉ㄦ剰** - * Date URL鍦↖E6/7涓笉鏀寔锛屾墍浠ヤ笉鐢ㄨ皟鐢ㄦ鏂规硶浜嗭紝鐩存帴鏄剧ず涓�寮犳殏涓嶆敮鎸侀瑙堝浘鐗囧ソ浜嗐�� - * - * - * @method makeThumb - * @grammar makeThumb( file, callback ) => undefined - * @grammar makeThumb( file, callback, width, height ) => undefined - * @for Uploader - * @example - * - * uploader.on( 'fileQueued', function( file ) { - * var $li = ...; - * - * uploader.makeThumb( file, function( error, ret ) { - * if ( error ) { - * $li.text('棰勮閿欒'); - * } else { - * $li.append('<img alt="" src="' + ret + '" />'); - * } - * }); - * - * }); - */ - makeThumb: function( file, cb, width, height ) { - var opts, image; - - file = this.request( 'get-file', file ); - - // 鍙瑙堝浘鐗囨牸寮忋�� - if ( !file.type.match( /^image/ ) ) { - cb( true ); - return; - } - - opts = $.extend({}, this.options.thumb ); - - // 濡傛灉浼犲叆鐨勬槸object. - if ( $.isPlainObject( width ) ) { - opts = $.extend( opts, width ); - width = null; - } - - width = width || opts.width; - height = height || opts.height; - - image = new Image( opts ); - - image.once( 'load', function() { - file._info = file._info || image.info(); - file._meta = file._meta || image.meta(); - image.resize( width, height ); - }); - - image.once( 'complete', function() { - cb( false, image.getAsDataUrl( opts.type ) ); - image.destroy(); - }); - - image.once( 'error', function() { - cb( true ); - image.destroy(); - }); - - throttle( image, file.source.size, function() { - file._info && image.info( file._info ); - file._meta && image.meta( file._meta ); - image.loadFromBlob( file.source ); - }); - }, - - compressImage: function( file ) { - var opts = this.options.compress || this.options.resize, - compressSize = opts && opts.compressSize || 300 * 1024, - image, deferred; - - file = this.request( 'get-file', file ); - - // 鍙瑙堝浘鐗囨牸寮忋�� - if ( !opts || !~'image/jpeg,image/jpg'.indexOf( file.type ) || - file.size < compressSize || - file._compressed ) { - return; - } - - opts = $.extend({}, opts ); - deferred = Base.Deferred(); - - image = new Image( opts ); - - deferred.always(function() { - image.destroy(); - image = null; - }); - image.once( 'error', deferred.reject ); - image.once( 'load', function() { - file._info = file._info || image.info(); - file._meta = file._meta || image.meta(); - image.resize( opts.width, opts.height ); - }); - - image.once( 'complete', function() { - var blob, size; - - // 绉诲姩绔� UC / qq 娴忚鍣ㄧ殑鏃犲浘妯″紡涓� - // ctx.getImageData 澶勭悊澶у浘鐨勬椂鍊欎細鎶� Exception - // INDEX_SIZE_ERR: DOM Exception 1 - try { - blob = image.getAsBlob( opts.type ); - - size = file.size; - - // 濡傛灉鍘嬬缉鍚庯紝姣斿師鏉ヨ繕澶у垯涓嶇敤鍘嬬缉鍚庣殑銆� - if ( blob.size < size ) { - // file.source.destroy && file.source.destroy(); - file.source = blob; - file.size = blob.size; - - file.trigger( 'resize', blob.size, size ); - } - - // 鏍囪锛岄伩鍏嶉噸澶嶅帇缂┿�� - file._compressed = true; - deferred.resolve(); - } catch ( e ) { - // 鍑洪敊浜嗙洿鎺ョ户缁紝璁╁叾涓婁紶鍘熷鍥剧墖 - deferred.resolve(); - } - }); - - file._info && image.info( file._info ); - file._meta && image.meta( file._meta ); - - image.loadFromBlob( file.source ); - return deferred.promise(); - } - }); - }); - /** - * @fileOverview 鏂囦欢灞炴�у皝瑁� - */ - define('file',[ - 'base', - 'mediator' - ], function( Base, Mediator ) { - - var $ = Base.$, - idPrefix = 'WU_FILE_', - idSuffix = 0, - rExt = /\.([^.]+)$/, - statusMap = {}; - - function gid() { - return idPrefix + idSuffix++; - } - - /** - * 鏂囦欢绫� - * @class File - * @constructor 鏋勯�犲嚱鏁� - * @grammar new File( source ) => File - * @param {Lib.File} source [lib.File](#Lib.File)瀹炰緥, 姝ource瀵硅薄鏄甫鏈塕untime淇℃伅鐨勩�� - */ - function WUFile( source ) { - - /** - * 鏂囦欢鍚嶏紝鍖呮嫭鎵╁睍鍚嶏紙鍚庣紑锛� - * @property name - * @type {string} - */ - this.name = source.name || 'Untitled'; - - /** - * 鏂囦欢浣撶Н锛堝瓧鑺傦級 - * @property size - * @type {uint} - * @default 0 - */ - this.size = source.size || 0; - - /** - * 鏂囦欢MIMETYPE绫诲瀷锛屼笌鏂囦欢绫诲瀷鐨勫搴斿叧绯昏鍙傝�僛http://t.cn/z8ZnFny](http://t.cn/z8ZnFny) - * @property type - * @type {string} - * @default 'application' - */ - this.type = source.type || 'application'; - - /** - * 鏂囦欢鏈�鍚庝慨鏀规棩鏈� - * @property lastModifiedDate - * @type {int} - * @default 褰撳墠鏃堕棿鎴� - */ - this.lastModifiedDate = source.lastModifiedDate || (new Date() * 1); - - /** - * 鏂囦欢ID锛屾瘡涓璞″叿鏈夊敮涓�ID锛屼笌鏂囦欢鍚嶆棤鍏� - * @property id - * @type {string} - */ - this.id = gid(); - - /** - * 鏂囦欢鎵╁睍鍚嶏紝閫氳繃鏂囦欢鍚嶈幏鍙栵紝渚嬪test.png鐨勬墿灞曞悕涓簆ng - * @property ext - * @type {string} - */ - this.ext = rExt.exec( this.name ) ? RegExp.$1 : ''; - - - /** - * 鐘舵�佹枃瀛楄鏄庛�傚湪涓嶅悓鐨剆tatus璇涓嬫湁涓嶅悓鐨勭敤閫斻�� - * @property statusText - * @type {string} - */ - this.statusText = ''; - - // 瀛樺偍鏂囦欢鐘舵�侊紝闃叉閫氳繃灞炴�х洿鎺ヤ慨鏀� - statusMap[ this.id ] = WUFile.Status.INITED; - - this.source = source; - this.loaded = 0; - - this.on( 'error', function( msg ) { - this.setStatus( WUFile.Status.ERROR, msg ); - }); - } - - $.extend( WUFile.prototype, { - - /** - * 璁剧疆鐘舵�侊紝鐘舵�佸彉鍖栨椂浼氳Е鍙慲change`浜嬩欢銆� - * @method setStatus - * @grammar setStatus( status[, statusText] ); - * @param {File.Status|String} status [鏂囦欢鐘舵�佸�糫(#WebUploader:File:File.Status) - * @param {String} [statusText=''] 鐘舵�佽鏄庯紝甯稿湪error鏃朵娇鐢紝鐢╤ttp, abort,server绛夋潵鏍囪鏄敱浜庝粈涔堝師鍥犲鑷存枃浠堕敊璇�� - */ - setStatus: function( status, text ) { - - var prevStatus = statusMap[ this.id ]; - - typeof text !== 'undefined' && (this.statusText = text); - - if ( status !== prevStatus ) { - statusMap[ this.id ] = status; - /** - * 鏂囦欢鐘舵�佸彉鍖� - * @event statuschange - */ - this.trigger( 'statuschange', status, prevStatus ); - } - - }, - - /** - * 鑾峰彇鏂囦欢鐘舵�� - * @return {File.Status} - * @example - 鏂囦欢鐘舵�佸叿浣撳寘鎷互涓嬪嚑绉嶇被鍨嬶細 - { - // 鍒濆鍖� - INITED: 0, - // 宸插叆闃熷垪 - QUEUED: 1, - // 姝e湪涓婁紶 - PROGRESS: 2, - // 涓婁紶鍑洪敊 - ERROR: 3, - // 涓婁紶鎴愬姛 - COMPLETE: 4, - // 涓婁紶鍙栨秷 - CANCELLED: 5 - } - */ - getStatus: function() { - return statusMap[ this.id ]; - }, - - /** - * 鑾峰彇鏂囦欢鍘熷淇℃伅銆� - * @return {*} - */ - getSource: function() { - return this.source; - }, - - destory: function() { - delete statusMap[ this.id ]; - } - }); - - Mediator.installTo( WUFile.prototype ); - - /** - * 鏂囦欢鐘舵�佸�硷紝鍏蜂綋鍖呮嫭浠ヤ笅鍑犵绫诲瀷锛� - * * `inited` 鍒濆鐘舵�� - * * `queued` 宸茬粡杩涘叆闃熷垪, 绛夊緟涓婁紶 - * * `progress` 涓婁紶涓� - * * `complete` 涓婁紶瀹屾垚銆� - * * `error` 涓婁紶鍑洪敊锛屽彲閲嶈瘯 - * * `interrupt` 涓婁紶涓柇锛屽彲缁紶銆� - * * `invalid` 鏂囦欢涓嶅悎鏍硷紝涓嶈兘閲嶈瘯涓婁紶銆備細鑷姩浠庨槦鍒椾腑绉婚櫎銆� - * * `cancelled` 鏂囦欢琚Щ闄ゃ�� - * @property {Object} Status - * @namespace File - * @class File - * @static - */ - WUFile.Status = { - INITED: 'inited', // 鍒濆鐘舵�� - QUEUED: 'queued', // 宸茬粡杩涘叆闃熷垪, 绛夊緟涓婁紶 - PROGRESS: 'progress', // 涓婁紶涓� - ERROR: 'error', // 涓婁紶鍑洪敊锛屽彲閲嶈瘯 - COMPLETE: 'complete', // 涓婁紶瀹屾垚銆� - CANCELLED: 'cancelled', // 涓婁紶鍙栨秷銆� - INTERRUPT: 'interrupt', // 涓婁紶涓柇锛屽彲缁紶銆� - INVALID: 'invalid' // 鏂囦欢涓嶅悎鏍硷紝涓嶈兘閲嶈瘯涓婁紶銆� - }; - - return WUFile; - }); - - /** - * @fileOverview 鏂囦欢闃熷垪 - */ - define('queue',[ - 'base', - 'mediator', - 'file' - ], function( Base, Mediator, WUFile ) { - - var $ = Base.$, - STATUS = WUFile.Status; - - /** - * 鏂囦欢闃熷垪, 鐢ㄦ潵瀛樺偍鍚勪釜鐘舵�佷腑鐨勬枃浠躲�� - * @class Queue - * @extends Mediator - */ - function Queue() { - - /** - * 缁熻鏂囦欢鏁般�� - * * `numOfQueue` 闃熷垪涓殑鏂囦欢鏁般�� - * * `numOfSuccess` 涓婁紶鎴愬姛鐨勬枃浠舵暟 - * * `numOfCancel` 琚Щ闄ょ殑鏂囦欢鏁� - * * `numOfProgress` 姝e湪涓婁紶涓殑鏂囦欢鏁� - * * `numOfUploadFailed` 涓婁紶閿欒鐨勬枃浠舵暟銆� - * * `numOfInvalid` 鏃犳晥鐨勬枃浠舵暟銆� - * @property {Object} stats - */ - this.stats = { - numOfQueue: 0, - numOfSuccess: 0, - numOfCancel: 0, - numOfProgress: 0, - numOfUploadFailed: 0, - numOfInvalid: 0 - }; - - // 涓婁紶闃熷垪锛屼粎鍖呮嫭绛夊緟涓婁紶鐨勬枃浠� - this._queue = []; - - // 瀛樺偍鎵�鏈夋枃浠� - this._map = {}; - } - - $.extend( Queue.prototype, { - - /** - * 灏嗘柊鏂囦欢鍔犲叆瀵归槦鍒楀熬閮� - * - * @method append - * @param {File} file 鏂囦欢瀵硅薄 - */ - append: function( file ) { - this._queue.push( file ); - this._fileAdded( file ); - return this; - }, - - /** - * 灏嗘柊鏂囦欢鍔犲叆瀵归槦鍒楀ご閮� - * - * @method prepend - * @param {File} file 鏂囦欢瀵硅薄 - */ - prepend: function( file ) { - this._queue.unshift( file ); - this._fileAdded( file ); - return this; - }, - - /** - * 鑾峰彇鏂囦欢瀵硅薄 - * - * @method getFile - * @param {String} fileId 鏂囦欢ID - * @return {File} - */ - getFile: function( fileId ) { - if ( typeof fileId !== 'string' ) { - return fileId; - } - return this._map[ fileId ]; - }, - - /** - * 浠庨槦鍒椾腑鍙栧嚭涓�涓寚瀹氱姸鎬佺殑鏂囦欢銆� - * @grammar fetch( status ) => File - * @method fetch - * @param {String} status [鏂囦欢鐘舵�佸�糫(#WebUploader:File:File.Status) - * @return {File} [File](#WebUploader:File) - */ - fetch: function( status ) { - var len = this._queue.length, - i, file; - - status = status || STATUS.QUEUED; - - for ( i = 0; i < len; i++ ) { - file = this._queue[ i ]; - - if ( status === file.getStatus() ) { - return file; - } - } - - return null; - }, - - /** - * 瀵归槦鍒楄繘琛屾帓搴忥紝鑳藉鎺у埗鏂囦欢涓婁紶椤哄簭銆� - * @grammar sort( fn ) => undefined - * @method sort - * @param {Function} fn 鎺掑簭鏂规硶 - */ - sort: function( fn ) { - if ( typeof fn === 'function' ) { - this._queue.sort( fn ); - } - }, - - /** - * 鑾峰彇鎸囧畾绫诲瀷鐨勬枃浠跺垪琛�, 鍒楄〃涓瘡涓�涓垚鍛樹负[File](#WebUploader:File)瀵硅薄銆� - * @grammar getFiles( [status1[, status2 ...]] ) => Array - * @method getFiles - * @param {String} [status] [鏂囦欢鐘舵�佸�糫(#WebUploader:File:File.Status) - */ - getFiles: function() { - var sts = [].slice.call( arguments, 0 ), - ret = [], - i = 0, - len = this._queue.length, - file; - - for ( ; i < len; i++ ) { - file = this._queue[ i ]; - - if ( sts.length && !~$.inArray( file.getStatus(), sts ) ) { - continue; - } - - ret.push( file ); - } - - return ret; - }, - - _fileAdded: function( file ) { - var me = this, - existing = this._map[ file.id ]; - - if ( !existing ) { - this._map[ file.id ] = file; - - file.on( 'statuschange', function( cur, pre ) { - me._onFileStatusChange( cur, pre ); - }); - } - - file.setStatus( STATUS.QUEUED ); - }, - - _onFileStatusChange: function( curStatus, preStatus ) { - var stats = this.stats; - - switch ( preStatus ) { - case STATUS.PROGRESS: - stats.numOfProgress--; - break; - - case STATUS.QUEUED: - stats.numOfQueue --; - break; - - case STATUS.ERROR: - stats.numOfUploadFailed--; - break; - - case STATUS.INVALID: - stats.numOfInvalid--; - break; - } - - switch ( curStatus ) { - case STATUS.QUEUED: - stats.numOfQueue++; - break; - - case STATUS.PROGRESS: - stats.numOfProgress++; - break; - - case STATUS.ERROR: - stats.numOfUploadFailed++; - break; - - case STATUS.COMPLETE: - stats.numOfSuccess++; - break; - - case STATUS.CANCELLED: - stats.numOfCancel++; - break; - - case STATUS.INVALID: - stats.numOfInvalid++; - break; - } - } - - }); - - Mediator.installTo( Queue.prototype ); - - return Queue; - }); - /** - * @fileOverview 闃熷垪 - */ - define('widgets/queue',[ - 'base', - 'uploader', - 'queue', - 'file', - 'lib/file', - 'runtime/client', - 'widgets/widget' - ], function( Base, Uploader, Queue, WUFile, File, RuntimeClient ) { - - var $ = Base.$, - rExt = /\.\w+$/, - Status = WUFile.Status; - - return Uploader.register({ - 'sort-files': 'sortFiles', - 'add-file': 'addFiles', - 'get-file': 'getFile', - 'fetch-file': 'fetchFile', - 'get-stats': 'getStats', - 'get-files': 'getFiles', - 'remove-file': 'removeFile', - 'retry': 'retry', - 'reset': 'reset', - 'accept-file': 'acceptFile' - }, { - - 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杩愯鏃讹紝閭e氨绠椾簡銆� - // 涓嶆墽琛屽悗缁搷浣� - if ( this.request('predict-runtime-type') !== 'html5' ) { - return; - } - - // 鍒涘缓涓�涓� html5 杩愯鏃剁殑 placeholder - // 浠ヨ嚦浜庡閮ㄦ坊鍔犲師鐢� File 瀵硅薄鐨勬椂鍊欒兘姝g‘鍖呰9涓�涓嬩緵 webuploader 浣跨敤銆� - deferred = Base.Deferred(); - runtime = new RuntimeClient('Placeholder'); - runtime.connectRuntime({ - runtimeOrder: 'html5' - }, function() { - me._ruid = runtime.getRuid(); - deferred.resolve(); - }); - return deferred.promise(); - }, - - - // 涓轰簡鏀寔澶栭儴鐩存帴娣诲姞涓�涓師鐢烣ile瀵硅薄銆� - _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 < 6 || this.accept && - - // 濡傛灉鍚嶅瓧涓湁鍚庣紑锛屾墠鍋氬悗缂�鐧藉悕鍗曞鐞嗐�� - rExt.exec( file.name ) && !this.accept.test( file.name ); - - return !invalid; - }, - - - /** - * @event beforeFileQueued - * @param {File} file File瀵硅薄 - * @description 褰撴枃浠惰鍔犲叆闃熷垪涔嬪墠瑙﹀彂锛屾浜嬩欢鐨刪andler杩斿洖鍊间负`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 - */ - - /** - * @method addFiles - * @grammar addFiles( file ) => undefined - * @grammar addFiles( [file1, file2 ...] ) => undefined - * @param {Array of File or File} [files] Files 瀵硅薄 鏁扮粍 - * @description 娣诲姞鏂囦欢鍒伴槦鍒� - * @for Uploader - */ - addFiles: function( files ) { - var me = this; - - if ( !files.length ) { - files = [ files ]; - } - - files = $.map( files, function( file ) { - return me._addFile( file ); - }); - - me.owner.trigger( 'filesQueued', files ); - - if ( me.options.auto ) { - me.request('start-upload'); - } - }, - - getStats: function() { - return this.stats; - }, - - /** - * @event fileDequeued - * @param {File} file File瀵硅薄 - * @description 褰撴枃浠惰绉婚櫎闃熷垪鍚庤Е鍙戙�� - * @for Uploader - */ - - /** - * @method removeFile - * @grammar removeFile( file ) => undefined - * @grammar removeFile( id ) => undefined - * @param {File|id} file File瀵硅薄鎴栬繖File瀵硅薄鐨刬d - * @description 绉婚櫎鏌愪竴鏂囦欢銆� - * @for Uploader - * @example - * - * $li.on('click', '.remove-this', function() { - * uploader.removeFile( file ); - * }) - */ - removeFile: function( file ) { - var me = this; - - file = file.id ? file : me.queue.getFile( file ); - - file.setStatus( Status.CANCELLED ); - me.owner.trigger( 'fileDequeued', 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 ); - }, - - /** - * @method reset - * @grammar reset() => undefined - * @description 閲嶇疆uploader銆傜洰鍓嶅彧閲嶇疆浜嗛槦鍒椼�� - * @for Uploader - * @example - * uploader.reset(); - */ - reset: function() { - this.queue = new Queue(); - this.stats = this.queue.stats; - } - }); - - }); - /** - * @fileOverview 娣诲姞鑾峰彇Runtime鐩稿叧淇℃伅鐨勬柟娉曘�� - */ - define('widgets/runtime',[ - 'uploader', - 'runtime/runtime', - 'widgets/widget' - ], function( Uploader, Runtime ) { - - Uploader.support = function() { - return Runtime.hasRuntime.apply( Runtime, arguments ); - }; - - return Uploader.register({ - 'predict-runtime-type': 'predictRuntmeType' - }, { - - init: function() { - if ( !this.predictRuntmeType() ) { - throw Error('Runtime Error'); - } - }, - - /** - * 棰勬祴Uploader灏嗛噰鐢ㄥ摢涓猔Runtime` - * @grammar predictRuntmeType() => String - * @method predictRuntmeType - * @for Uploader - */ - predictRuntmeType: function() { - var orders = this.options.runtimeOrder || Runtime.orders, - type = this.type, - i, len; - - if ( !type ) { - orders = orders.split( /\s*,\s*/g ); - - for ( i = 0, len = orders.length; i < len; i++ ) { - if ( Runtime.hasRuntime( orders[ i ] ) ) { - this.type = type = orders[ i ]; - break; - } - } - } - - return type; - } - }); - }); - /** - * @fileOverview Transport - */ - define('lib/transport',[ - 'base', - 'runtime/client', - 'mediator' - ], function( Base, RuntimeClient, Mediator ) { - - var $ = Base.$; - - function Transport( opts ) { - var me = this; - - opts = me.options = $.extend( true, {}, Transport.options, opts || {} ); - RuntimeClient.call( this, 'Transport' ); - - this._blob = null; - this._formData = opts.formData || {}; - this._headers = opts.headers || {}; - - this.on( 'progress', this._timeout ); - this.on( 'load error', function() { - me.trigger( 'progress', 1 ); - clearTimeout( me._timer ); - }); - } - - Transport.options = { - server: '', - method: 'POST', - - // 璺ㄥ煙鏃讹紝鏄惁鍏佽鎼哄甫cookie, 鍙湁html5 runtime鎵嶆湁鏁� - withCredentials: false, - fileVal: 'file', - timeout: 2 * 60 * 1000, // 2鍒嗛挓 - formData: {}, - headers: {}, - sendAsBinary: false - }; - - $.extend( Transport.prototype, { - - // 娣诲姞Blob, 鍙兘娣诲姞涓�娆★紝鏈�鍚庝竴娆℃湁鏁堛�� - appendBlob: function( key, blob, filename ) { - var me = this, - opts = me.options; - - if ( me.getRuid() ) { - me.disconnectRuntime(); - } - - // 杩炴帴鍒癰lob褰掑睘鐨勫悓涓�涓猺untime. - me.connectRuntime( blob.ruid, function() { - me.exec('init'); - }); - - me._blob = blob; - opts.fileVal = key || opts.fileVal; - opts.filename = filename || opts.filename; - }, - - // 娣诲姞鍏朵粬瀛楁 - append: function( key, value ) { - if ( typeof key === 'object' ) { - $.extend( this._formData, key ); - } else { - this._formData[ key ] = value; - } - }, - - setRequestHeader: function( key, value ) { - if ( typeof key === 'object' ) { - $.extend( this._headers, key ); - } else { - this._headers[ key ] = value; - } - }, - - send: function( method ) { - this.exec( 'send', method ); - this._timeout(); - }, - - abort: function() { - clearTimeout( this._timer ); - return this.exec('abort'); - }, - - destroy: function() { - this.trigger('destroy'); - this.off(); - this.exec('destroy'); - this.disconnectRuntime(); - }, - - getResponse: function() { - return this.exec('getResponse'); - }, - - getResponseAsJson: function() { - return this.exec('getResponseAsJson'); - }, - - getStatus: function() { - return this.exec('getStatus'); - }, - - _timeout: function() { - var me = this, - duration = me.options.timeout; - - if ( !duration ) { - return; - } - - clearTimeout( me._timer ); - me._timer = setTimeout(function() { - me.abort(); - me.trigger( 'error', 'timeout' ); - }, duration ); - } - - }); - - // 璁㏕ransport鍏峰浜嬩欢鍔熻兘銆� - Mediator.installTo( Transport.prototype ); - - return Transport; - }); - /** - * @fileOverview 璐熻矗鏂囦欢涓婁紶鐩稿叧銆� - */ - define('widgets/upload',[ - 'base', - 'uploader', - 'file', - 'lib/transport', - 'widgets/widget' - ], function( Base, Uploader, WUFile, Transport ) { - - var $ = Base.$, - isPromise = Base.isPromise, - Status = WUFile.Status; - - // 娣诲姞榛樿閰嶇疆椤� - $.extend( Uploader.options, { - - - /** - * @property {Boolean} [prepareNextFile=false] - * @namespace options - * @for Uploader - * @description 鏄惁鍏佽鍦ㄦ枃浠朵紶杈撴椂鎻愬墠鎶婁笅涓�涓枃浠跺噯澶囧ソ銆� - * 瀵逛簬涓�涓枃浠剁殑鍑嗗宸ヤ綔姣旇緝鑰楁椂锛屾瘮濡傚浘鐗囧帇缂╋紝md5搴忓垪鍖栥�� - * 濡傛灉鑳芥彁鍓嶅湪褰撳墠鏂囦欢浼犺緭鏈熷鐞嗭紝鍙互鑺傜渷鎬讳綋鑰楁椂銆� - */ - prepareNextFile: false, - - /** - * @property {Boolean} [chunked=false] - * @namespace options - * @for Uploader - * @description 鏄惁瑕佸垎鐗囧鐞嗗ぇ鏂囦欢涓婁紶銆� - */ - chunked: false, - - /** - * @property {Boolean} [chunkSize=5242880] - * @namespace options - * @for Uploader - * @description 濡傛灉瑕佸垎鐗囷紝鍒嗗澶т竴鐗囷紵 榛樿澶у皬涓�5M. - */ - chunkSize: 5 * 1024 * 1024, - - /** - * @property {Boolean} [chunkRetry=2] - * @namespace options - * @for Uploader - * @description 濡傛灉鏌愪釜鍒嗙墖鐢变簬缃戠粶闂鍑洪敊锛屽厑璁歌嚜鍔ㄩ噸浼犲灏戞锛� - */ - chunkRetry: 2, - - /** - * @property {Boolean} [threads=3] - * @namespace options - * @for Uploader - * @description 涓婁紶骞跺彂鏁般�傚厑璁稿悓鏃舵渶澶т笂浼犺繘绋嬫暟銆� - */ - threads: 3, - - - /** - * @property {Object} [formData] - * @namespace options - * @for Uploader - * @description 鏂囦欢涓婁紶璇锋眰鐨勫弬鏁拌〃锛屾瘡娆″彂閫侀兘浼氬彂閫佹瀵硅薄涓殑鍙傛暟銆� - */ - formData: null - - /** - * @property {Object} [fileVal='file'] - * @namespace options - * @for Uploader - * @description 璁剧疆鏂囦欢涓婁紶鍩熺殑name銆� - */ - - /** - * @property {Object} [method='POST'] - * @namespace options - * @for Uploader - * @description 鏂囦欢涓婁紶鏂瑰紡锛宍POST`鎴栬�卄GET`銆� - */ - - /** - * @property {Object} [sendAsBinary=false] - * @namespace options - * @for Uploader - * @description 鏄惁宸蹭簩杩涘埗鐨勬祦鐨勬柟寮忓彂閫佹枃浠讹紝杩欐牱鏁翠釜涓婁紶鍐呭`php://input`閮戒负鏂囦欢鍐呭锛� - * 鍏朵粬鍙傛暟鍦�$_GET鏁扮粍涓�� - */ - }); - - // 璐熻矗灏嗘枃浠跺垏鐗囥�� - function CuteFile( file, chunkSize ) { - var pending = [], - blob = file.source, - total = blob.size, - chunks = chunkSize ? Math.ceil( total / chunkSize ) : 1, - start = 0, - index = 0, - len; - - while ( index < chunks ) { - len = Math.min( chunkSize, total - start ); - - pending.push({ - file: file, - start: start, - end: chunkSize ? (start + len) : total, - total: total, - chunks: chunks, - chunk: index++ - }); - start += len; - } - - file.blocks = pending.concat(); - file.remaning = pending.length; - - return { - file: file, - - has: function() { - return !!pending.length; - }, - - fetch: function() { - return pending.shift(); - } - }; - } - - Uploader.register({ - 'start-upload': 'start', - 'stop-upload': 'stop', - 'skip-file': 'skipFile', - 'is-in-progress': 'isInProgress' - }, { - - init: function() { - var owner = this.owner; - - this.runing = false; - - // 璁板綍褰撳墠姝e湪浼犵殑鏁版嵁锛岃窡threads鐩稿叧 - this.pool = []; - - // 缂撳瓨鍗冲皢涓婁紶鐨勬枃浠躲�� - this.pending = []; - - // 璺熻釜杩樻湁澶氬皯鍒嗙墖娌℃湁瀹屾垚涓婁紶銆� - this.remaning = 0; - this.__tick = Base.bindFn( this._tick, this ); - - owner.on( 'uploadComplete', function( file ) { - // 鎶婂叾浠栧潡鍙栨秷浜嗐�� - file.blocks && $.each( file.blocks, function( _, v ) { - v.transport && (v.transport.abort(), v.transport.destroy()); - delete v.transport; - }); - - delete file.blocks; - delete file.remaning; - }); - }, - - /** - * @event startUpload - * @description 褰撳紑濮嬩笂浼犳祦绋嬫椂瑙﹀彂銆� - * @for Uploader - */ - - /** - * 寮�濮嬩笂浼犮�傛鏂规硶鍙互浠庡垵濮嬬姸鎬佽皟鐢ㄥ紑濮嬩笂浼犳祦绋嬶紝涔熷彲浠ヤ粠鏆傚仠鐘舵�佽皟鐢紝缁х画涓婁紶娴佺▼銆� - * @grammar upload() => undefined - * @method upload - * @for Uploader - */ - start: function() { - var me = this; - - // 绉诲嚭invalid鐨勬枃浠� - $.each( me.request( 'get-files', Status.INVALID ), function() { - me.request( 'remove-file', this ); - }); - - if ( me.runing ) { - return; - } - - me.runing = true; - - // 濡傛灉鏈夋殏鍋滅殑锛屽垯缁紶 - $.each( me.pool, function( _, v ) { - var file = v.file; - - if ( file.getStatus() === Status.INTERRUPT ) { - file.setStatus( Status.PROGRESS ); - me._trigged = false; - v.transport && v.transport.send(); - } - }); - - me._trigged = false; - me.owner.trigger('startUpload'); - Base.nextTick( me.__tick ); - }, - - /** - * @event stopUpload - * @description 褰撳紑濮嬩笂浼犳祦绋嬫殏鍋滄椂瑙﹀彂銆� - * @for Uploader - */ - - /** - * 鏆傚仠涓婁紶銆傜涓�涓弬鏁颁负鏄惁涓柇涓婁紶褰撳墠姝e湪涓婁紶鐨勬枃浠躲�� - * @grammar stop() => undefined - * @grammar stop( true ) => undefined - * @method stop - * @for Uploader - */ - stop: function( interrupt ) { - var me = this; - - if ( me.runing === false ) { - return; - } - - me.runing = false; - - interrupt && $.each( me.pool, function( _, v ) { - v.transport && v.transport.abort(); - v.file.setStatus( Status.INTERRUPT ); - }); - - me.owner.trigger('stopUpload'); - }, - - /** - * 鍒ゆ柇`Uplaode`r鏄惁姝e湪涓婁紶涓�� - * @grammar isInProgress() => Boolean - * @method isInProgress - * @for Uploader - */ - isInProgress: function() { - return !!this.runing; - }, - - getStats: function() { - return this.request('get-stats'); - }, - - /** - * 鎺夎繃涓�涓枃浠朵笂浼狅紝鐩存帴鏍囪鎸囧畾鏂囦欢涓哄凡涓婁紶鐘舵�併�� - * @grammar skipFile( file ) => undefined - * @method skipFile - * @for Uploader - */ - skipFile: function( file, status ) { - file = this.request( 'get-file', file ); - - file.setStatus( status || Status.COMPLETE ); - file.skipped = true; - - // 濡傛灉姝e湪涓婁紶銆� - file.blocks && $.each( file.blocks, function( _, v ) { - var _tr = v.transport; - - if ( _tr ) { - _tr.abort(); - _tr.destroy(); - delete v.transport; - } - }); - - this.owner.trigger( 'uploadSkip', file ); - }, - - /** - * @event uploadFinished - * @description 褰撴墍鏈夋枃浠朵笂浼犵粨鏉熸椂瑙﹀彂銆� - * @for Uploader - */ - _tick: function() { - var me = this, - opts = me.options, - fn, val; - - // 涓婁竴涓猵romise杩樻病鏈夌粨鏉燂紝鍒欑瓑寰呭畬鎴愬悗鍐嶆墽琛屻�� - if ( me._promise ) { - return me._promise.always( me.__tick ); - } - - // 杩樻湁浣嶇疆锛屼笖杩樻湁鏂囦欢瑕佸鐞嗙殑璇濄�� - if ( me.pool.length < opts.threads && (val = me._nextBlock()) ) { - me._trigged = false; - - fn = function( val ) { - me._promise = null; - - // 鏈夊彲鑳芥槸reject杩囨潵鐨勶紝鎵�浠ヨ妫�娴媣al鐨勭被鍨嬨�� - val && val.file && me._startSend( val ); - Base.nextTick( me.__tick ); - }; - - me._promise = isPromise( val ) ? val.always( fn ) : fn( val ); - - // 娌℃湁瑕佷笂浼犵殑浜嗭紝涓旀病鏈夋鍦ㄤ紶杈撶殑浜嗐�� - } else if ( !me.remaning && !me.getStats().numOfQueue ) { - me.runing = false; - - me._trigged || Base.nextTick(function() { - me.owner.trigger('uploadFinished'); - }); - me._trigged = true; - } - }, - - _nextBlock: function() { - var me = this, - act = me._act, - opts = me.options, - next, done; - - // 濡傛灉褰撳墠鏂囦欢杩樻湁娌℃湁闇�瑕佷紶杈撶殑锛屽垯鐩存帴杩斿洖鍓╀笅鐨勩�� - if ( act && act.has() && - act.file.getStatus() === Status.PROGRESS ) { - - // 鏄惁鎻愬墠鍑嗗涓嬩竴涓枃浠� - if ( opts.prepareNextFile && !me.pending.length ) { - me._prepareNextFile(); - } - - return act.fetch(); - - // 鍚﹀垯锛屽鏋滄鍦ㄨ繍琛岋紝鍒欏噯澶囦笅涓�涓枃浠讹紝骞剁瓑寰呭畬鎴愬悗杩斿洖涓嬩釜鍒嗙墖銆� - } else if ( me.runing ) { - - // 濡傛灉缂撳瓨涓湁锛屽垯鐩存帴鍦ㄧ紦瀛樹腑鍙栵紝娌℃湁鍒欏幓queue涓彇銆� - if ( !me.pending.length && me.getStats().numOfQueue ) { - me._prepareNextFile(); - } - - next = me.pending.shift(); - done = function( file ) { - if ( !file ) { - return null; - } - - act = CuteFile( file, opts.chunked ? opts.chunkSize : 0 ); - me._act = act; - return act.fetch(); - }; - - // 鏂囦欢鍙兘杩樺湪prepare涓紝涔熸湁鍙兘宸茬粡瀹屽叏鍑嗗濂戒簡銆� - return isPromise( next ) ? - next[ next.pipe ? 'pipe' : 'then']( done ) : - done( next ); - } - }, - - - /** - * @event uploadStart - * @param {File} file File瀵硅薄 - * @description 鏌愪釜鏂囦欢寮�濮嬩笂浼犲墠瑙﹀彂锛屼竴涓枃浠跺彧浼氳Е鍙戜竴娆°�� - * @for Uploader - */ - _prepareNextFile: function() { - var me = this, - file = me.request('fetch-file'), - pending = me.pending, - promise; - - if ( file ) { - promise = me.request( 'before-send-file', file, function() { - - // 鏈夊彲鑳芥枃浠惰skip鎺変簡銆傛枃浠惰skip鎺夊悗锛岀姸鎬佸潙瀹氫笉鏄疩ueued. - if ( file.getStatus() === Status.QUEUED ) { - me.owner.trigger( 'uploadStart', file ); - file.setStatus( Status.PROGRESS ); - return file; - } - - return me._finishFile( file ); - }); - - // 濡傛灉杩樺湪pending涓紝鍒欐浛鎹㈡垚鏂囦欢鏈韩銆� - promise.done(function() { - var idx = $.inArray( promise, pending ); - - ~idx && pending.splice( idx, 1, file ); - }); - - // befeore-send-file鐨勯挬瀛愬氨鏈夐敊璇彂鐢熴�� - promise.fail(function( reason ) { - file.setStatus( Status.ERROR, reason ); - me.owner.trigger( 'uploadError', file, reason ); - me.owner.trigger( 'uploadComplete', file ); - }); - - pending.push( promise ); - } - }, - - // 璁╁嚭浣嶇疆浜嗭紝鍙互璁╁叾浠栧垎鐗囧紑濮嬩笂浼� - _popBlock: function( block ) { - var idx = $.inArray( block, this.pool ); - - this.pool.splice( idx, 1 ); - block.file.remaning--; - this.remaning--; - }, - - // 寮�濮嬩笂浼狅紝鍙互琚帀杩囥�傚鏋減romise琚玶eject浜嗭紝鍒欒〃绀鸿烦杩囨鍒嗙墖銆� - _startSend: function( block ) { - var me = this, - file = block.file, - promise; - - me.pool.push( block ); - me.remaning++; - - // 濡傛灉娌℃湁鍒嗙墖锛屽垯鐩存帴浣跨敤鍘熷鐨勩�� - // 涓嶄細涓㈠けcontent-type淇℃伅銆� - block.blob = block.chunks === 1 ? file.source : - file.source.slice( block.start, block.end ); - - // hook, 姣忎釜鍒嗙墖鍙戦�佷箣鍓嶅彲鑳借鍋氫簺寮傛鐨勪簨鎯呫�� - promise = me.request( 'before-send', block, function() { - - // 鏈夊彲鑳芥枃浠跺凡缁忎笂浼犲嚭閿欎簡锛屾墍浠ヤ笉闇�瑕佸啀浼犺緭浜嗐�� - if ( file.getStatus() === Status.PROGRESS ) { - me._doSend( block ); - } else { - me._popBlock( block ); - Base.nextTick( me.__tick ); - } - }); - - // 濡傛灉涓篺ail浜嗭紝鍒欒烦杩囨鍒嗙墖銆� - promise.fail(function() { - if ( file.remaning === 1 ) { - me._finishFile( file ).always(function() { - block.percentage = 1; - me._popBlock( block ); - me.owner.trigger( 'uploadComplete', file ); - Base.nextTick( me.__tick ); - }); - } else { - block.percentage = 1; - me._popBlock( block ); - Base.nextTick( me.__tick ); - } - }); - }, - - - /** - * @event uploadBeforeSend - * @param {Object} object - * @param {Object} data 榛樿鐨勪笂浼犲弬鏁帮紝鍙互鎵╁睍姝ゅ璞℃潵鎺у埗涓婁紶鍙傛暟銆� - * @description 褰撴煇涓枃浠剁殑鍒嗗潡鍦ㄥ彂閫佸墠瑙﹀彂锛屼富瑕佺敤鏉ヨ闂槸鍚﹁娣诲姞闄勫甫鍙傛暟锛屽ぇ鏂囦欢鍦ㄥ紑璧峰垎鐗囦笂浼犵殑鍓嶆彁涓嬫浜嬩欢鍙兘浼氳Е鍙戝娆°�� - * @for Uploader - */ - - /** - * @event uploadAccept - * @param {Object} object - * @param {Object} ret 鏈嶅姟绔殑杩斿洖鏁版嵁锛宩son鏍煎紡锛屽鏋滄湇鍔$涓嶆槸json鏍煎紡锛屼粠ret._raw涓彇鏁版嵁锛岃嚜琛岃В鏋愩�� - * @description 褰撴煇涓枃浠朵笂浼犲埌鏈嶅姟绔搷搴斿悗锛屼細娲鹃�佹浜嬩欢鏉ヨ闂湇鍔$鍝嶅簲鏄惁鏈夋晥銆傚鏋滄浜嬩欢handler杩斿洖鍊间负`false`, 鍒欐鏂囦欢灏嗘淳閫乣server`绫诲瀷鐨刞uploadError`浜嬩欢銆� - * @for Uploader - */ - - /** - * @event uploadProgress - * @param {File} file File瀵硅薄 - * @param {Number} percentage 涓婁紶杩涘害 - * @description 涓婁紶杩囩▼涓Е鍙戯紝鎼哄甫涓婁紶杩涘害銆� - * @for Uploader - */ - - - /** - * @event uploadError - * @param {File} file File瀵硅薄 - * @param {String} reason 鍑洪敊鐨刢ode - * @description 褰撴枃浠朵笂浼犲嚭閿欐椂瑙﹀彂銆� - * @for Uploader - */ - - /** - * @event uploadSuccess - * @param {File} file File瀵硅薄 - * @param {Object} response 鏈嶅姟绔繑鍥炵殑鏁版嵁 - * @description 褰撴枃浠朵笂浼犳垚鍔熸椂瑙﹀彂銆� - * @for Uploader - */ - - /** - * @event uploadComplete - * @param {File} [file] File瀵硅薄 - * @description 涓嶇鎴愬姛鎴栬�呭け璐ワ紝鏂囦欢涓婁紶瀹屾垚鏃惰Е鍙戙�� - * @for Uploader - */ - - // 鍋氫笂浼犳搷浣溿�� - _doSend: function( block ) { - var me = this, - owner = me.owner, - opts = me.options, - file = block.file, - tr = new Transport( opts ), - data = $.extend({}, opts.formData ), - headers = $.extend({}, opts.headers ), - requestAccept, ret; - - block.transport = tr; - - tr.on( 'destroy', function() { - delete block.transport; - me._popBlock( block ); - Base.nextTick( me.__tick ); - }); - - // 骞挎挱涓婁紶杩涘害銆備互鏂囦欢涓哄崟浣嶃�� - tr.on( 'progress', function( percentage ) { - var totalPercent = 0, - uploaded = 0; - - // 鍙兘娌℃湁abort鎺夛紝progress杩樻槸鎵ц杩涙潵浜嗐�� - // if ( !file.blocks ) { - // return; - // } - - totalPercent = block.percentage = percentage; - - if ( block.chunks > 1 ) { // 璁$畻鏂囦欢鐨勬暣浣撻�熷害銆� - $.each( file.blocks, function( _, v ) { - uploaded += (v.percentage || 0) * (v.end - v.start); - }); - - totalPercent = uploaded / file.size; - } - - owner.trigger( 'uploadProgress', file, totalPercent || 0 ); - }); - - // 鐢ㄦ潵璇㈤棶锛屾槸鍚﹁繑鍥炵殑缁撴灉鏄湁閿欒鐨勩�� - requestAccept = function( reject ) { - var fn; - - ret = tr.getResponseAsJson() || {}; - ret._raw = tr.getResponse(); - fn = function( value ) { - reject = value; - }; - - // 鏈嶅姟绔搷搴斾簡锛屼笉浠h〃鎴愬姛浜嗭紝璇㈤棶鏄惁鍝嶅簲姝g‘銆� - if ( !owner.trigger( 'uploadAccept', block, ret, fn ) ) { - reject = reject || 'server'; - } - - return reject; - }; - - // 灏濊瘯閲嶈瘯锛岀劧鍚庡箍鎾枃浠朵笂浼犲嚭閿欍�� - tr.on( 'error', function( type, flag ) { - block.retried = block.retried || 0; - - // 鑷姩閲嶈瘯 - if ( block.chunks > 1 && ~'http,abort'.indexOf( type ) && - block.retried < opts.chunkRetry ) { - - block.retried++; - tr.send(); - - } else { - - // http status 500 ~ 600 - if ( !flag && type === 'server' ) { - type = requestAccept( type ); - } - - file.setStatus( Status.ERROR, type ); - owner.trigger( 'uploadError', file, type ); - owner.trigger( 'uploadComplete', file ); - } - }); - - // 涓婁紶鎴愬姛 - tr.on( 'load', function() { - var reason; - - // 濡傛灉闈為鏈燂紝杞悜涓婁紶鍑洪敊銆� - if ( (reason = requestAccept()) ) { - tr.trigger( 'error', reason, true ); - return; - } - - // 鍏ㄩ儴涓婁紶瀹屾垚銆� - if ( file.remaning === 1 ) { - me._finishFile( file, ret ); - } else { - tr.destroy(); - } - }); - - // 閰嶇疆榛樿鐨勪笂浼犲瓧娈点�� - data = $.extend( data, { - id: file.id, - name: file.name, - type: file.type, - lastModifiedDate: file.lastModifiedDate, - size: file.size - }); - - block.chunks > 1 && $.extend( data, { - chunks: block.chunks, - chunk: block.chunk - }); - - // 鍦ㄥ彂閫佷箣闂村彲浠ユ坊鍔犲瓧娈典粈涔堢殑銆傘�傘�� - // 濡傛灉榛樿鐨勫瓧娈典笉澶熶娇鐢紝鍙互閫氳繃鐩戝惉姝や簨浠舵潵鎵╁睍 - owner.trigger( 'uploadBeforeSend', block, data, headers ); - - // 寮�濮嬪彂閫併�� - tr.appendBlob( opts.fileVal, block.blob, file.name ); - tr.append( data ); - tr.setRequestHeader( headers ); - tr.send(); - }, - - // 瀹屾垚涓婁紶銆� - _finishFile: function( file, ret, hds ) { - var owner = this.owner; - - return owner - .request( 'after-send-file', arguments, function() { - file.setStatus( Status.COMPLETE ); - owner.trigger( 'uploadSuccess', file, ret, hds ); - }) - .fail(function( reason ) { - - // 濡傛灉澶栭儴宸茬粡鏍囪涓篿nvalid浠�涔堢殑锛屼笉鍐嶆敼鐘舵�併�� - if ( file.getStatus() === Status.PROGRESS ) { - file.setStatus( Status.ERROR, reason ); - } - - owner.trigger( 'uploadError', file, reason ); - }) - .always(function() { - owner.trigger( 'uploadComplete', file ); - }); - } - - }); - }); - /** - * @fileOverview 鍚勭楠岃瘉锛屽寘鎷枃浠舵�诲ぇ灏忔槸鍚﹁秴鍑恒�佸崟鏂囦欢鏄惁瓒呭嚭鍜屾枃浠舵槸鍚﹂噸澶嶃�� - */ - - define('widgets/validator',[ - 'base', - 'uploader', - 'file', - 'widgets/widget' - ], function( Base, Uploader, WUFile ) { - - var $ = Base.$, - validators = {}, - api; - - /** - * @event error - * @param {String} type 閿欒绫诲瀷銆� - * @description 褰搗alidate涓嶉�氳繃鏃讹紝浼氫互娲鹃�侀敊璇簨浠剁殑褰㈠紡閫氱煡璋冪敤鑰呫�傞�氳繃`upload.on('error', handler)`鍙互鎹曡幏鍒版绫婚敊璇紝鐩墠鏈変互涓嬮敊璇細鍦ㄧ壒瀹氱殑鎯呭喌涓嬫淳閫侀敊鏉ャ�� - * - * * `Q_EXCEED_NUM_LIMIT` 鍦ㄨ缃簡`fileNumLimit`涓斿皾璇曠粰`uploader`娣诲姞鐨勬枃浠舵暟閲忚秴鍑鸿繖涓�兼椂娲鹃�併�� - * * `Q_EXCEED_SIZE_LIMIT` 鍦ㄨ缃簡`Q_EXCEED_SIZE_LIMIT`涓斿皾璇曠粰`uploader`娣诲姞鐨勬枃浠舵�诲ぇ灏忚秴鍑鸿繖涓�兼椂娲鹃�併�� - * @for Uploader - */ - - // 鏆撮湶缁欏闈㈢殑api - api = { - - // 娣诲姞楠岃瘉鍣� - addValidator: function( type, cb ) { - validators[ type ] = cb; - }, - - // 绉婚櫎楠岃瘉鍣� - removeValidator: function( type ) { - delete validators[ type ]; - } - }; - - // 鍦║ploader鍒濆鍖栫殑鏃跺�欏惎鍔╒alidators鐨勫垵濮嬪寲 - Uploader.register({ - init: function() { - var me = this; - $.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 = opts.fileNumLimit >> 0, - 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( 'uploadFinished', 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 = opts.fileSizeLimit >> 0, - 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( 'uploadFinished', 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', file ); - return false; - } - - }); - - }); - - /** - * @property {int} [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 ]); - }); - }); - - return api; - }); - - /** - * @fileOverview Runtime绠$悊鍣紝璐熻矗Runtime鐨勯�夋嫨, 杩炴帴 - */ - define('runtime/compbase',[],function() { - - function CompBase( owner, runtime ) { - - this.owner = owner; - this.options = owner.options; - - this.getRuntime = function() { - return runtime; - }; - - this.getRuid = function() { - return runtime.uid; - }; - - this.trigger = function() { - return owner.trigger.apply( owner, arguments ); - }; - } - - return CompBase; - }); - /** - * @fileOverview Html5Runtime - */ - define('runtime/html5/runtime',[ - 'base', - 'runtime/runtime', - 'runtime/compbase' - ], function( Base, Runtime, CompBase ) { - - var type = 'html5', - components = {}; - - function Html5Runtime() { - var pool = {}, - me = this, - destory = this.destory; - - Runtime.apply( me, arguments ); - me.type = type; - - - // 杩欎釜鏂规硶鐨勮皟鐢ㄨ�咃紝瀹為檯涓婃槸RuntimeClient - me.exec = function( comp, fn/*, args...*/) { - var client = this, - uid = client.uid, - args = Base.slice( arguments, 2 ), - instance; - - if ( components[ comp ] ) { - instance = pool[ uid ] = pool[ uid ] || - new components[ comp ]( client, me ); - - if ( instance[ fn ] ) { - return instance[ fn ].apply( instance, args ); - } - } - }; - - me.destory = function() { - // @todo 鍒犻櫎姹犲瓙涓殑鎵�鏈夊疄渚� - return destory && destory.apply( this, arguments ); - }; - } - - Base.inherits( Runtime, { - constructor: Html5Runtime, - - // 涓嶉渶瑕佽繛鎺ュ叾浠栫▼搴忥紝鐩存帴鎵цcallback - init: function() { - var me = this; - setTimeout(function() { - me.trigger('ready'); - }, 1 ); - } - - }); - - // 娉ㄥ唽Components - Html5Runtime.register = function( name, component ) { - var klass = components[ name ] = Base.inherits( CompBase, component ); - return klass; - }; - - // 娉ㄥ唽html5杩愯鏃躲�� - // 鍙湁鍦ㄦ敮鎸佺殑鍓嶆彁涓嬫敞鍐屻�� - if ( window.Blob && window.FileReader && window.DataView ) { - Runtime.addRuntime( type, Html5Runtime ); - } - - return Html5Runtime; - }); - /** - * @fileOverview Blob Html瀹炵幇 - */ - define('runtime/html5/blob',[ - 'runtime/html5/runtime', - 'lib/blob' - ], function( Html5Runtime, Blob ) { - - return Html5Runtime.register( 'Blob', { - slice: function( start, end ) { - var blob = this.owner.source, - slice = blob.slice || blob.webkitSlice || blob.mozSlice; - - blob = slice.call( blob, start, end ); - - return new Blob( this.getRuid(), blob ); - } - }); - }); - /** - * @fileOverview FilePaste - */ - define('runtime/html5/dnd',[ - 'base', - 'runtime/html5/runtime', - 'lib/file' - ], function( Base, Html5Runtime, File ) { - - var $ = Base.$, - prefix = 'webuploader-dnd-'; - - return Html5Runtime.register( 'DragAndDrop', { - init: function() { - var elem = this.elem = this.options.container; - - this.dragEnterHandler = Base.bindFn( this._dragEnterHandler, this ); - this.dragOverHandler = Base.bindFn( this._dragOverHandler, this ); - this.dragLeaveHandler = Base.bindFn( this._dragLeaveHandler, this ); - this.dropHandler = Base.bindFn( this._dropHandler, this ); - this.dndOver = false; - - elem.on( 'dragenter', this.dragEnterHandler ); - elem.on( 'dragover', this.dragOverHandler ); - elem.on( 'dragleave', this.dragLeaveHandler ); - elem.on( 'drop', this.dropHandler ); - - if ( this.options.disableGlobalDnd ) { - $( document ).on( 'dragover', this.dragOverHandler ); - $( document ).on( 'drop', this.dropHandler ); - } - }, - - _dragEnterHandler: function( e ) { - var me = this, - denied = me._denied || false, - items; - - e = e.originalEvent || e; - - if ( !me.dndOver ) { - me.dndOver = true; - - // 娉ㄦ剰鍙湁 chrome 鏀寔銆� - items = e.dataTransfer.items; - - if ( items && items.length ) { - me._denied = denied = !me.trigger( 'accept', items ); - } - - me.elem.addClass( prefix + 'over' ); - me.elem[ denied ? 'addClass' : - 'removeClass' ]( prefix + 'denied' ); - } - - - e.dataTransfer.dropEffect = denied ? 'none' : 'copy'; - - return false; - }, - - _dragOverHandler: function( e ) { - // 鍙鐞嗘鍐呯殑銆� - var parentElem = this.elem.parent().get( 0 ); - if ( parentElem && !$.contains( parentElem, e.currentTarget ) ) { - return false; - } - - clearTimeout( this._leaveTimer ); - this._dragEnterHandler.call( this, e ); - - return false; - }, - - _dragLeaveHandler: function() { - var me = this, - handler; - - handler = function() { - me.dndOver = false; - me.elem.removeClass( prefix + 'over ' + prefix + 'denied' ); - }; - - clearTimeout( me._leaveTimer ); - me._leaveTimer = setTimeout( handler, 100 ); - return false; - }, - - _dropHandler: function( e ) { - var me = this, - ruid = me.getRuid(), - parentElem = me.elem.parent().get( 0 ); - - // 鍙鐞嗘鍐呯殑銆� - if ( parentElem && !$.contains( parentElem, e.currentTarget ) ) { - return false; - } - - me._getTansferFiles( e, function( results ) { - me.trigger( 'drop', $.map( results, function( file ) { - return new File( ruid, file ); - }) ); - }); - - me.dndOver = false; - me.elem.removeClass( prefix + 'over' ); - return false; - }, - - // 濡傛灉浼犲叆 callback 鍒欏幓鏌ョ湅鏂囦欢澶癸紝鍚﹀垯鍙褰撳墠鏂囦欢澶广�� - _getTansferFiles: function( e, callback ) { - var results = [], - promises = [], - items, files, dataTransfer, file, item, i, len, canAccessFolder; - - e = e.originalEvent || e; - - dataTransfer = e.dataTransfer; - items = dataTransfer.items; - files = dataTransfer.files; - - canAccessFolder = !!(items && items[ 0 ].webkitGetAsEntry); - - for ( i = 0, len = files.length; i < len; i++ ) { - file = files[ i ]; - item = items && items[ i ]; - - if ( canAccessFolder && item.webkitGetAsEntry().isDirectory ) { - - promises.push( this._traverseDirectoryTree( - item.webkitGetAsEntry(), results ) ); - } else { - results.push( file ); - } - } - - Base.when.apply( Base, promises ).done(function() { - - if ( !results.length ) { - return; - } - - callback( results ); - }); - }, - - _traverseDirectoryTree: function( entry, results ) { - var deferred = Base.Deferred(), - me = this; - - if ( entry.isFile ) { - entry.file(function( file ) { - results.push( file ); - deferred.resolve(); - }); - } else if ( entry.isDirectory ) { - entry.createReader().readEntries(function( entries ) { - var len = entries.length, - promises = [], - arr = [], // 涓轰簡淇濊瘉椤哄簭銆� - i; - - for ( i = 0; i < len; i++ ) { - promises.push( me._traverseDirectoryTree( - entries[ i ], arr ) ); - } - - Base.when.apply( Base, promises ).then(function() { - results.push.apply( results, arr ); - deferred.resolve(); - }, deferred.reject ); - }); - } - - return deferred.promise(); - }, - - destroy: function() { - var elem = this.elem; - - elem.off( 'dragenter', this.dragEnterHandler ); - elem.off( 'dragover', this.dragEnterHandler ); - elem.off( 'dragleave', this.dragLeaveHandler ); - elem.off( 'drop', this.dropHandler ); - - if ( this.options.disableGlobalDnd ) { - $( document ).off( 'dragover', this.dragOverHandler ); - $( document ).off( 'drop', this.dropHandler ); - } - } - }); - }); - - /** - * @fileOverview FilePaste - */ - define('runtime/html5/filepaste',[ - 'base', - 'runtime/html5/runtime', - 'lib/file' - ], function( Base, Html5Runtime, File ) { - - return Html5Runtime.register( 'FilePaste', { - init: function() { - var opts = this.options, - elem = this.elem = opts.container, - accept = '.*', - arr, i, len, item; - - // accetp鐨刴imeTypes涓敓鎴愬尮閰嶆鍒欍�� - if ( opts.accept ) { - arr = []; - - for ( i = 0, len = opts.accept.length; i < len; i++ ) { - item = opts.accept[ i ].mimeTypes; - item && arr.push( item ); - } - - if ( arr.length ) { - accept = arr.join(','); - accept = accept.replace( /,/g, '|' ).replace( /\*/g, '.*' ); - } - } - this.accept = accept = new RegExp( accept, 'i' ); - this.hander = Base.bindFn( this._pasteHander, this ); - elem.on( 'paste', this.hander ); - }, - - _pasteHander: function( e ) { - var allowed = [], - ruid = this.getRuid(), - items, item, blob, i, len; - - e = e.originalEvent || e; - items = e.clipboardData.items; - - for ( i = 0, len = items.length; i < len; i++ ) { - item = items[ i ]; - - if ( item.kind !== 'file' || !(blob = item.getAsFile()) ) { - continue; - } - - allowed.push( new File( ruid, blob ) ); - } - - if ( allowed.length ) { - // 涓嶉樆姝㈤潪鏂囦欢绮樿创锛堟枃瀛楃矘璐达級鐨勪簨浠跺啋娉� - e.preventDefault(); - e.stopPropagation(); - this.trigger( 'paste', allowed ); - } - }, - - destroy: function() { - this.elem.off( 'paste', this.hander ); - } - }); - }); - - /** - * @fileOverview FilePicker - */ - define('runtime/html5/filepicker',[ - 'base', - 'runtime/html5/runtime' - ], function( Base, Html5Runtime ) { - - var $ = Base.$; - - return Html5Runtime.register( 'FilePicker', { - init: function() { - var container = this.getRuntime().getContainer(), - me = this, - owner = me.owner, - opts = me.options, - lable = $( document.createElement('label') ), - input = $( document.createElement('input') ), - arr, i, len, mouseHandler; - - input.attr( 'type', 'file' ); - input.attr( 'name', opts.name ); - input.addClass('webuploader-element-invisible'); - - lable.on( 'click', function() { - input.trigger('click'); - }); - - lable.css({ - opacity: 0, - width: '100%', - height: '100%', - display: 'block', - cursor: 'pointer', - background: '#ffffff' - }); - - if ( opts.multiple ) { - input.attr( 'multiple', 'multiple' ); - } - - // @todo Firefox涓嶆敮鎸佸崟鐙寚瀹氬悗缂� - if ( opts.accept && opts.accept.length > 0 ) { - arr = []; - - for ( i = 0, len = opts.accept.length; i < len; i++ ) { - arr.push( opts.accept[ i ].mimeTypes ); - } - - input.attr( 'accept', arr.join(',') ); - } - - container.append( input ); - container.append( lable ); - - mouseHandler = function( e ) { - owner.trigger( e.type ); - }; - - input.on( 'change', function( e ) { - var fn = arguments.callee, - clone; - - me.files = e.target.files; - - // reset input - clone = this.cloneNode( true ); - this.parentNode.replaceChild( clone, this ); - - input.off(); - input = $( clone ).on( 'change', fn ) - .on( 'mouseenter mouseleave', mouseHandler ); - - owner.trigger('change'); - }); - - lable.on( 'mouseenter mouseleave', mouseHandler ); - - }, - - - getFiles: function() { - return this.files; - }, - - destroy: function() { - // todo - } - }); - }); - /** - * Terms: - * - * Uint8Array, FileReader, BlobBuilder, atob, ArrayBuffer - * @fileOverview Image鎺т欢 - */ - define('runtime/html5/util',[ - 'base' - ], function( Base ) { - - var urlAPI = window.createObjectURL && window || - window.URL && URL.revokeObjectURL && URL || - window.webkitURL, - createObjectURL = Base.noop, - revokeObjectURL = createObjectURL; - - if ( urlAPI ) { - - // 鏇村畨鍏ㄧ殑鏂瑰紡璋冪敤锛屾瘮濡俛ndroid閲岄潰灏辫兘鎶奵ontext鏀规垚鍏朵粬鐨勫璞°�� - createObjectURL = function() { - return urlAPI.createObjectURL.apply( urlAPI, arguments ); - }; - - revokeObjectURL = function() { - return urlAPI.revokeObjectURL.apply( urlAPI, arguments ); - }; - } - - return { - createObjectURL: createObjectURL, - revokeObjectURL: revokeObjectURL, - - dataURL2Blob: function( dataURI ) { - var byteStr, intArray, ab, i, mimetype, parts; - - parts = dataURI.split(','); - - if ( ~parts[ 0 ].indexOf('base64') ) { - byteStr = atob( parts[ 1 ] ); - } else { - byteStr = decodeURIComponent( parts[ 1 ] ); - } - - ab = new ArrayBuffer( byteStr.length ); - intArray = new Uint8Array( ab ); - - for ( i = 0; i < byteStr.length; i++ ) { - intArray[ i ] = byteStr.charCodeAt( i ); - } - - mimetype = parts[ 0 ].split(':')[ 1 ].split(';')[ 0 ]; - - return this.arrayBufferToBlob( ab, mimetype ); - }, - - dataURL2ArrayBuffer: function( dataURI ) { - var byteStr, intArray, i, parts; - - parts = dataURI.split(','); - - if ( ~parts[ 0 ].indexOf('base64') ) { - byteStr = atob( parts[ 1 ] ); - } else { - byteStr = decodeURIComponent( parts[ 1 ] ); - } - - intArray = new Uint8Array( byteStr.length ); - - for ( i = 0; i < byteStr.length; i++ ) { - intArray[ i ] = byteStr.charCodeAt( i ); - } - - return intArray.buffer; - }, - - arrayBufferToBlob: function( buffer, type ) { - var builder = window.BlobBuilder || window.WebKitBlobBuilder, - bb; - - // android涓嶆敮鎸佺洿鎺ew Blob, 鍙兘鍊熷姪blobbuilder. - if ( builder ) { - bb = new builder(); - bb.append( buffer ); - return bb.getBlob( type ); - } - - return new Blob([ buffer ], type ? { type: type } : {} ); - }, - - // 鎶藉嚭鏉ヤ富瑕佹槸涓轰簡瑙e喅android涓嬮潰canvas.toDataUrl涓嶆敮鎸乯peg. - // 浣犲緱鍒扮殑缁撴灉鏄痯ng. - canvasToDataUrl: function( canvas, type, quality ) { - return canvas.toDataURL( type, quality / 100 ); - }, - - // imagemeat浼氬鍐欒繖涓柟娉曪紝濡傛灉鐢ㄦ埛閫夋嫨鍔犺浇閭d釜鏂囦欢浜嗙殑璇濄�� - parseMeta: function( blob, callback ) { - callback( false, {}); - }, - - // imagemeat浼氬鍐欒繖涓柟娉曪紝濡傛灉鐢ㄦ埛閫夋嫨鍔犺浇閭d釜鏂囦欢浜嗙殑璇濄�� - updateImageHead: function( data ) { - return data; - } - }; - }); - /** - * Terms: - * - * Uint8Array, FileReader, BlobBuilder, atob, ArrayBuffer - * @fileOverview Image鎺т欢 - */ - define('runtime/html5/imagemeta',[ - 'runtime/html5/util' - ], function( Util ) { - - var api; - - api = { - parsers: { - 0xffe1: [] - }, - - maxMetaDataSize: 262144, - - parse: function( blob, cb ) { - var me = this, - fr = new FileReader(); - - fr.onload = function() { - cb( false, me._parse( this.result ) ); - fr = fr.onload = fr.onerror = null; - }; - - fr.onerror = function( e ) { - cb( e.message ); - fr = fr.onload = fr.onerror = null; - }; - - blob = blob.slice( 0, me.maxMetaDataSize ); - fr.readAsArrayBuffer( blob.getSource() ); - }, - - _parse: function( buffer, noParse ) { - if ( buffer.byteLength < 6 ) { - return; - } - - var dataview = new DataView( buffer ), - offset = 2, - maxOffset = dataview.byteLength - 4, - headLength = offset, - ret = {}, - markerBytes, markerLength, parsers, i; - - if ( dataview.getUint16( 0 ) === 0xffd8 ) { - - while ( offset < maxOffset ) { - markerBytes = dataview.getUint16( offset ); - - if ( markerBytes >= 0xffe0 && markerBytes <= 0xffef || - markerBytes === 0xfffe ) { - - markerLength = dataview.getUint16( offset + 2 ) + 2; - - if ( offset + markerLength > dataview.byteLength ) { - break; - } - - parsers = api.parsers[ markerBytes ]; - - if ( !noParse && parsers ) { - for ( i = 0; i < parsers.length; i += 1 ) { - parsers[ i ].call( api, dataview, offset, - markerLength, ret ); - } - } - - offset += markerLength; - headLength = offset; - } else { - break; - } - } - - if ( headLength > 6 ) { - if ( buffer.slice ) { - ret.imageHead = buffer.slice( 2, headLength ); - } else { - // Workaround for IE10, which does not yet - // support ArrayBuffer.slice: - ret.imageHead = new Uint8Array( buffer ) - .subarray( 2, headLength ); - } - } - } - - return ret; - }, - - updateImageHead: function( buffer, head ) { - var data = this._parse( buffer, true ), - buf1, buf2, bodyoffset; - - - bodyoffset = 2; - if ( data.imageHead ) { - bodyoffset = 2 + data.imageHead.byteLength; - } - - if ( buffer.slice ) { - buf2 = buffer.slice( bodyoffset ); - } else { - buf2 = new Uint8Array( buffer ).subarray( bodyoffset ); - } - - buf1 = new Uint8Array( head.byteLength + 2 + buf2.byteLength ); - - buf1[ 0 ] = 0xFF; - buf1[ 1 ] = 0xD8; - buf1.set( new Uint8Array( head ), 2 ); - buf1.set( new Uint8Array( buf2 ), head.byteLength + 2 ); - - return buf1.buffer; - } - }; - - Util.parseMeta = function() { - return api.parse.apply( api, arguments ); - }; - - Util.updateImageHead = function() { - return api.updateImageHead.apply( api, arguments ); - }; - - return api; - }); - /** - * 浠g爜鏉ヨ嚜浜庯細https://github.com/blueimp/JavaScript-Load-Image - * 鏆傛椂椤圭洰涓彧鐢ㄤ簡orientation. - * - * 鍘婚櫎浜� Exif Sub IFD Pointer, GPS Info IFD Pointer, Exif Thumbnail. - * @fileOverview EXIF瑙f瀽 - */ - - // Sample - // ==================================== - // Make : Apple - // Model : iPhone 4S - // Orientation : 1 - // XResolution : 72 [72/1] - // YResolution : 72 [72/1] - // ResolutionUnit : 2 - // Software : QuickTime 7.7.1 - // DateTime : 2013:09:01 22:53:55 - // ExifIFDPointer : 190 - // ExposureTime : 0.058823529411764705 [1/17] - // FNumber : 2.4 [12/5] - // ExposureProgram : Normal program - // ISOSpeedRatings : 800 - // ExifVersion : 0220 - // DateTimeOriginal : 2013:09:01 22:52:51 - // DateTimeDigitized : 2013:09:01 22:52:51 - // ComponentsConfiguration : YCbCr - // ShutterSpeedValue : 4.058893515764426 - // ApertureValue : 2.5260688216892597 [4845/1918] - // BrightnessValue : -0.3126686601998395 - // MeteringMode : Pattern - // Flash : Flash did not fire, compulsory flash mode - // FocalLength : 4.28 [107/25] - // SubjectArea : [4 values] - // FlashpixVersion : 0100 - // ColorSpace : 1 - // PixelXDimension : 2448 - // PixelYDimension : 3264 - // SensingMethod : One-chip color area sensor - // ExposureMode : 0 - // WhiteBalance : Auto white balance - // FocalLengthIn35mmFilm : 35 - // SceneCaptureType : Standard - define('runtime/html5/imagemeta/exif',[ - 'base', - 'runtime/html5/imagemeta' - ], function( Base, ImageMeta ) { - - var EXIF = {}; - - EXIF.ExifMap = function() { - return this; - }; - - EXIF.ExifMap.prototype.map = { - 'Orientation': 0x0112 - }; - - EXIF.ExifMap.prototype.get = function( id ) { - return this[ id ] || this[ this.map[ id ] ]; - }; - - EXIF.exifTagTypes = { - // byte, 8-bit unsigned int: - 1: { - getValue: function( dataView, dataOffset ) { - return dataView.getUint8( dataOffset ); - }, - size: 1 - }, - - // ascii, 8-bit byte: - 2: { - getValue: function( dataView, dataOffset ) { - return String.fromCharCode( dataView.getUint8( dataOffset ) ); - }, - size: 1, - ascii: true - }, - - // short, 16 bit int: - 3: { - getValue: function( dataView, dataOffset, littleEndian ) { - return dataView.getUint16( dataOffset, littleEndian ); - }, - size: 2 - }, - - // long, 32 bit int: - 4: { - getValue: function( dataView, dataOffset, littleEndian ) { - return dataView.getUint32( dataOffset, littleEndian ); - }, - size: 4 - }, - - // rational = two long values, - // first is numerator, second is denominator: - 5: { - getValue: function( dataView, dataOffset, littleEndian ) { - return dataView.getUint32( dataOffset, littleEndian ) / - dataView.getUint32( dataOffset + 4, littleEndian ); - }, - size: 8 - }, - - // slong, 32 bit signed int: - 9: { - getValue: function( dataView, dataOffset, littleEndian ) { - return dataView.getInt32( dataOffset, littleEndian ); - }, - size: 4 - }, - - // srational, two slongs, first is numerator, second is denominator: - 10: { - getValue: function( dataView, dataOffset, littleEndian ) { - return dataView.getInt32( dataOffset, littleEndian ) / - dataView.getInt32( dataOffset + 4, littleEndian ); - }, - size: 8 - } - }; - - // undefined, 8-bit byte, value depending on field: - EXIF.exifTagTypes[ 7 ] = EXIF.exifTagTypes[ 1 ]; - - EXIF.getExifValue = function( dataView, tiffOffset, offset, type, length, - littleEndian ) { - - var tagType = EXIF.exifTagTypes[ type ], - tagSize, dataOffset, values, i, str, c; - - if ( !tagType ) { - Base.log('Invalid Exif data: Invalid tag type.'); - return; - } - - tagSize = tagType.size * length; - - // Determine if the value is contained in the dataOffset bytes, - // or if the value at the dataOffset is a pointer to the actual data: - dataOffset = tagSize > 4 ? tiffOffset + dataView.getUint32( offset + 8, - littleEndian ) : (offset + 8); - - if ( dataOffset + tagSize > dataView.byteLength ) { - Base.log('Invalid Exif data: Invalid data offset.'); - return; - } - - if ( length === 1 ) { - return tagType.getValue( dataView, dataOffset, littleEndian ); - } - - values = []; - - for ( i = 0; i < length; i += 1 ) { - values[ i ] = tagType.getValue( dataView, - dataOffset + i * tagType.size, littleEndian ); - } - - if ( tagType.ascii ) { - str = ''; - - // Concatenate the chars: - for ( i = 0; i < values.length; i += 1 ) { - c = values[ i ]; - - // Ignore the terminating NULL byte(s): - if ( c === '\u0000' ) { - break; - } - str += c; - } - - return str; - } - return values; - }; - - EXIF.parseExifTag = function( dataView, tiffOffset, offset, littleEndian, - data ) { - - var tag = dataView.getUint16( offset, littleEndian ); - data.exif[ tag ] = EXIF.getExifValue( dataView, tiffOffset, offset, - dataView.getUint16( offset + 2, littleEndian ), // tag type - dataView.getUint32( offset + 4, littleEndian ), // tag length - littleEndian ); - }; - - EXIF.parseExifTags = function( dataView, tiffOffset, dirOffset, - littleEndian, data ) { - - var tagsNumber, dirEndOffset, i; - - if ( dirOffset + 6 > dataView.byteLength ) { - Base.log('Invalid Exif data: Invalid directory offset.'); - return; - } - - tagsNumber = dataView.getUint16( dirOffset, littleEndian ); - dirEndOffset = dirOffset + 2 + 12 * tagsNumber; - - if ( dirEndOffset + 4 > dataView.byteLength ) { - Base.log('Invalid Exif data: Invalid directory size.'); - return; - } - - for ( i = 0; i < tagsNumber; i += 1 ) { - this.parseExifTag( dataView, tiffOffset, - dirOffset + 2 + 12 * i, // tag offset - littleEndian, data ); - } - - // Return the offset to the next directory: - return dataView.getUint32( dirEndOffset, littleEndian ); - }; - - // EXIF.getExifThumbnail = function(dataView, offset, length) { - // var hexData, - // i, - // b; - // if (!length || offset + length > dataView.byteLength) { - // Base.log('Invalid Exif data: Invalid thumbnail data.'); - // return; - // } - // hexData = []; - // for (i = 0; i < length; i += 1) { - // b = dataView.getUint8(offset + i); - // hexData.push((b < 16 ? '0' : '') + b.toString(16)); - // } - // return 'data:image/jpeg,%' + hexData.join('%'); - // }; - - EXIF.parseExifData = function( dataView, offset, length, data ) { - - var tiffOffset = offset + 10, - littleEndian, dirOffset; - - // Check for the ASCII code for "Exif" (0x45786966): - if ( dataView.getUint32( offset + 4 ) !== 0x45786966 ) { - // No Exif data, might be XMP data instead - return; - } - if ( tiffOffset + 8 > dataView.byteLength ) { - Base.log('Invalid Exif data: Invalid segment size.'); - return; - } - - // Check for the two null bytes: - if ( dataView.getUint16( offset + 8 ) !== 0x0000 ) { - Base.log('Invalid Exif data: Missing byte alignment offset.'); - return; - } - - // Check the byte alignment: - switch ( dataView.getUint16( tiffOffset ) ) { - case 0x4949: - littleEndian = true; - break; - - case 0x4D4D: - littleEndian = false; - break; - - default: - Base.log('Invalid Exif data: Invalid byte alignment marker.'); - return; - } - - // Check for the TIFF tag marker (0x002A): - if ( dataView.getUint16( tiffOffset + 2, littleEndian ) !== 0x002A ) { - Base.log('Invalid Exif data: Missing TIFF marker.'); - return; - } - - // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal: - dirOffset = dataView.getUint32( tiffOffset + 4, littleEndian ); - // Create the exif object to store the tags: - data.exif = new EXIF.ExifMap(); - // Parse the tags of the main image directory and retrieve the - // offset to the next directory, usually the thumbnail directory: - dirOffset = EXIF.parseExifTags( dataView, tiffOffset, - tiffOffset + dirOffset, littleEndian, data ); - - // 灏濊瘯璇诲彇缂╃暐鍥� - // if ( dirOffset ) { - // thumbnailData = {exif: {}}; - // dirOffset = EXIF.parseExifTags( - // dataView, - // tiffOffset, - // tiffOffset + dirOffset, - // littleEndian, - // thumbnailData - // ); - - // // Check for JPEG Thumbnail offset: - // if (thumbnailData.exif[0x0201]) { - // data.exif.Thumbnail = EXIF.getExifThumbnail( - // dataView, - // tiffOffset + thumbnailData.exif[0x0201], - // thumbnailData.exif[0x0202] // Thumbnail data length - // ); - // } - // } - }; - - ImageMeta.parsers[ 0xffe1 ].push( EXIF.parseExifData ); - return EXIF; - }); - /** - * 杩欎釜鏂瑰紡鎬ц兘涓嶈锛屼絾鏄彲浠ヨВ鍐砤ndroid閲岄潰鐨則oDataUrl鐨刡ug - * android閲岄潰toDataUrl('image/jpege')寰楀埌鐨勭粨鏋滃嵈鏄痯ng. - * - * 鎵�浠ヨ繖閲屾病杈欙紝鍙兘鍊熷姪杩欎釜宸ュ叿 - * @fileOverview jpeg encoder - */ - define('runtime/html5/jpegencoder',[], function( require, exports, module ) { - - /* - Copyright (c) 2008, Adobe Systems Incorporated - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of Adobe Systems Incorporated nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - /* - JPEG encoder ported to JavaScript and optimized by Andreas Ritter, www.bytestrom.eu, 11/2009 - - Basic GUI blocking jpeg encoder - */ - - function JPEGEncoder(quality) { - var self = this; - var fround = Math.round; - var ffloor = Math.floor; - var YTable = new Array(64); - var UVTable = new Array(64); - var fdtbl_Y = new Array(64); - var fdtbl_UV = new Array(64); - var YDC_HT; - var UVDC_HT; - var YAC_HT; - var UVAC_HT; - - var bitcode = new Array(65535); - var category = new Array(65535); - var outputfDCTQuant = new Array(64); - var DU = new Array(64); - var byteout = []; - var bytenew = 0; - var bytepos = 7; - - var YDU = new Array(64); - var UDU = new Array(64); - var VDU = new Array(64); - var clt = new Array(256); - var RGB_YUV_TABLE = new Array(2048); - var currentQuality; - - var ZigZag = [ - 0, 1, 5, 6,14,15,27,28, - 2, 4, 7,13,16,26,29,42, - 3, 8,12,17,25,30,41,43, - 9,11,18,24,31,40,44,53, - 10,19,23,32,39,45,52,54, - 20,22,33,38,46,51,55,60, - 21,34,37,47,50,56,59,61, - 35,36,48,49,57,58,62,63 - ]; - - var std_dc_luminance_nrcodes = [0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0]; - var std_dc_luminance_values = [0,1,2,3,4,5,6,7,8,9,10,11]; - var std_ac_luminance_nrcodes = [0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d]; - var std_ac_luminance_values = [ - 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12, - 0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07, - 0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08, - 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0, - 0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16, - 0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28, - 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39, - 0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49, - 0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59, - 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69, - 0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79, - 0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89, - 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98, - 0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7, - 0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6, - 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5, - 0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4, - 0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2, - 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea, - 0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8, - 0xf9,0xfa - ]; - - var std_dc_chrominance_nrcodes = [0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0]; - var std_dc_chrominance_values = [0,1,2,3,4,5,6,7,8,9,10,11]; - var std_ac_chrominance_nrcodes = [0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77]; - var std_ac_chrominance_values = [ - 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21, - 0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71, - 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91, - 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0, - 0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34, - 0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26, - 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38, - 0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48, - 0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58, - 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68, - 0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78, - 0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87, - 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96, - 0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5, - 0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4, - 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3, - 0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2, - 0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda, - 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9, - 0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8, - 0xf9,0xfa - ]; - - function initQuantTables(sf){ - var YQT = [ - 16, 11, 10, 16, 24, 40, 51, 61, - 12, 12, 14, 19, 26, 58, 60, 55, - 14, 13, 16, 24, 40, 57, 69, 56, - 14, 17, 22, 29, 51, 87, 80, 62, - 18, 22, 37, 56, 68,109,103, 77, - 24, 35, 55, 64, 81,104,113, 92, - 49, 64, 78, 87,103,121,120,101, - 72, 92, 95, 98,112,100,103, 99 - ]; - - for (var i = 0; i < 64; i++) { - var t = ffloor((YQT[i]*sf+50)/100); - if (t < 1) { - t = 1; - } else if (t > 255) { - t = 255; - } - YTable[ZigZag[i]] = t; - } - var UVQT = [ - 17, 18, 24, 47, 99, 99, 99, 99, - 18, 21, 26, 66, 99, 99, 99, 99, - 24, 26, 56, 99, 99, 99, 99, 99, - 47, 66, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99 - ]; - for (var j = 0; j < 64; j++) { - var u = ffloor((UVQT[j]*sf+50)/100); - if (u < 1) { - u = 1; - } else if (u > 255) { - u = 255; - } - UVTable[ZigZag[j]] = u; - } - var aasf = [ - 1.0, 1.387039845, 1.306562965, 1.175875602, - 1.0, 0.785694958, 0.541196100, 0.275899379 - ]; - var k = 0; - for (var row = 0; row < 8; row++) - { - for (var col = 0; col < 8; col++) - { - fdtbl_Y[k] = (1.0 / (YTable [ZigZag[k]] * aasf[row] * aasf[col] * 8.0)); - fdtbl_UV[k] = (1.0 / (UVTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0)); - k++; - } - } - } - - function computeHuffmanTbl(nrcodes, std_table){ - var codevalue = 0; - var pos_in_table = 0; - var HT = new Array(); - for (var k = 1; k <= 16; k++) { - for (var j = 1; j <= nrcodes[k]; j++) { - HT[std_table[pos_in_table]] = []; - HT[std_table[pos_in_table]][0] = codevalue; - HT[std_table[pos_in_table]][1] = k; - pos_in_table++; - codevalue++; - } - codevalue*=2; - } - return HT; - } - - function initHuffmanTbl() - { - YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes,std_dc_luminance_values); - UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes,std_dc_chrominance_values); - YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes,std_ac_luminance_values); - UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes,std_ac_chrominance_values); - } - - function initCategoryNumber() - { - var nrlower = 1; - var nrupper = 2; - for (var cat = 1; cat <= 15; cat++) { - //Positive numbers - for (var nr = nrlower; nr<nrupper; nr++) { - category[32767+nr] = cat; - bitcode[32767+nr] = []; - bitcode[32767+nr][1] = cat; - bitcode[32767+nr][0] = nr; - } - //Negative numbers - for (var nrneg =-(nrupper-1); nrneg<=-nrlower; nrneg++) { - category[32767+nrneg] = cat; - bitcode[32767+nrneg] = []; - bitcode[32767+nrneg][1] = cat; - bitcode[32767+nrneg][0] = nrupper-1+nrneg; - } - nrlower <<= 1; - nrupper <<= 1; - } - } - - function initRGBYUVTable() { - for(var i = 0; i < 256;i++) { - RGB_YUV_TABLE[i] = 19595 * i; - RGB_YUV_TABLE[(i+ 256)>>0] = 38470 * i; - RGB_YUV_TABLE[(i+ 512)>>0] = 7471 * i + 0x8000; - RGB_YUV_TABLE[(i+ 768)>>0] = -11059 * i; - RGB_YUV_TABLE[(i+1024)>>0] = -21709 * i; - RGB_YUV_TABLE[(i+1280)>>0] = 32768 * i + 0x807FFF; - RGB_YUV_TABLE[(i+1536)>>0] = -27439 * i; - RGB_YUV_TABLE[(i+1792)>>0] = - 5329 * i; - } - } - - // IO functions - function writeBits(bs) - { - var value = bs[0]; - var posval = bs[1]-1; - while ( posval >= 0 ) { - if (value & (1 << posval) ) { - bytenew |= (1 << bytepos); - } - posval--; - bytepos--; - if (bytepos < 0) { - if (bytenew == 0xFF) { - writeByte(0xFF); - writeByte(0); - } - else { - writeByte(bytenew); - } - bytepos=7; - bytenew=0; - } - } - } - - function writeByte(value) - { - byteout.push(clt[value]); // write char directly instead of converting later - } - - function writeWord(value) - { - writeByte((value>>8)&0xFF); - writeByte((value )&0xFF); - } - - // DCT & quantization core - function fDCTQuant(data, fdtbl) - { - var d0, d1, d2, d3, d4, d5, d6, d7; - /* Pass 1: process rows. */ - var dataOff=0; - var i; - var I8 = 8; - var I64 = 64; - for (i=0; i<I8; ++i) - { - d0 = data[dataOff]; - d1 = data[dataOff+1]; - d2 = data[dataOff+2]; - d3 = data[dataOff+3]; - d4 = data[dataOff+4]; - d5 = data[dataOff+5]; - d6 = data[dataOff+6]; - d7 = data[dataOff+7]; - - var tmp0 = d0 + d7; - var tmp7 = d0 - d7; - var tmp1 = d1 + d6; - var tmp6 = d1 - d6; - var tmp2 = d2 + d5; - var tmp5 = d2 - d5; - var tmp3 = d3 + d4; - var tmp4 = d3 - d4; - - /* Even part */ - var tmp10 = tmp0 + tmp3; /* phase 2 */ - var tmp13 = tmp0 - tmp3; - var tmp11 = tmp1 + tmp2; - var tmp12 = tmp1 - tmp2; - - data[dataOff] = tmp10 + tmp11; /* phase 3 */ - data[dataOff+4] = tmp10 - tmp11; - - var z1 = (tmp12 + tmp13) * 0.707106781; /* c4 */ - data[dataOff+2] = tmp13 + z1; /* phase 5 */ - data[dataOff+6] = tmp13 - z1; - - /* Odd part */ - tmp10 = tmp4 + tmp5; /* phase 2 */ - tmp11 = tmp5 + tmp6; - tmp12 = tmp6 + tmp7; - - /* The rotator is modified from fig 4-8 to avoid extra negations. */ - var z5 = (tmp10 - tmp12) * 0.382683433; /* c6 */ - var z2 = 0.541196100 * tmp10 + z5; /* c2-c6 */ - var z4 = 1.306562965 * tmp12 + z5; /* c2+c6 */ - var z3 = tmp11 * 0.707106781; /* c4 */ - - var z11 = tmp7 + z3; /* phase 5 */ - var z13 = tmp7 - z3; - - data[dataOff+5] = z13 + z2; /* phase 6 */ - data[dataOff+3] = z13 - z2; - data[dataOff+1] = z11 + z4; - data[dataOff+7] = z11 - z4; - - dataOff += 8; /* advance pointer to next row */ - } - - /* Pass 2: process columns. */ - dataOff = 0; - for (i=0; i<I8; ++i) - { - d0 = data[dataOff]; - d1 = data[dataOff + 8]; - d2 = data[dataOff + 16]; - d3 = data[dataOff + 24]; - d4 = data[dataOff + 32]; - d5 = data[dataOff + 40]; - d6 = data[dataOff + 48]; - d7 = data[dataOff + 56]; - - var tmp0p2 = d0 + d7; - var tmp7p2 = d0 - d7; - var tmp1p2 = d1 + d6; - var tmp6p2 = d1 - d6; - var tmp2p2 = d2 + d5; - var tmp5p2 = d2 - d5; - var tmp3p2 = d3 + d4; - var tmp4p2 = d3 - d4; - - /* Even part */ - var tmp10p2 = tmp0p2 + tmp3p2; /* phase 2 */ - var tmp13p2 = tmp0p2 - tmp3p2; - var tmp11p2 = tmp1p2 + tmp2p2; - var tmp12p2 = tmp1p2 - tmp2p2; - - data[dataOff] = tmp10p2 + tmp11p2; /* phase 3 */ - data[dataOff+32] = tmp10p2 - tmp11p2; - - var z1p2 = (tmp12p2 + tmp13p2) * 0.707106781; /* c4 */ - data[dataOff+16] = tmp13p2 + z1p2; /* phase 5 */ - data[dataOff+48] = tmp13p2 - z1p2; - - /* Odd part */ - tmp10p2 = tmp4p2 + tmp5p2; /* phase 2 */ - tmp11p2 = tmp5p2 + tmp6p2; - tmp12p2 = tmp6p2 + tmp7p2; - - /* The rotator is modified from fig 4-8 to avoid extra negations. */ - var z5p2 = (tmp10p2 - tmp12p2) * 0.382683433; /* c6 */ - var z2p2 = 0.541196100 * tmp10p2 + z5p2; /* c2-c6 */ - var z4p2 = 1.306562965 * tmp12p2 + z5p2; /* c2+c6 */ - var z3p2 = tmp11p2 * 0.707106781; /* c4 */ - - var z11p2 = tmp7p2 + z3p2; /* phase 5 */ - var z13p2 = tmp7p2 - z3p2; - - data[dataOff+40] = z13p2 + z2p2; /* phase 6 */ - data[dataOff+24] = z13p2 - z2p2; - data[dataOff+ 8] = z11p2 + z4p2; - data[dataOff+56] = z11p2 - z4p2; - - dataOff++; /* advance pointer to next column */ - } - - // Quantize/descale the coefficients - var fDCTQuant; - for (i=0; i<I64; ++i) - { - // Apply the quantization and scaling factor & Round to nearest integer - fDCTQuant = data[i]*fdtbl[i]; - outputfDCTQuant[i] = (fDCTQuant > 0.0) ? ((fDCTQuant + 0.5)|0) : ((fDCTQuant - 0.5)|0); - //outputfDCTQuant[i] = fround(fDCTQuant); - - } - return outputfDCTQuant; - } - - function writeAPP0() - { - writeWord(0xFFE0); // marker - writeWord(16); // length - writeByte(0x4A); // J - writeByte(0x46); // F - writeByte(0x49); // I - writeByte(0x46); // F - writeByte(0); // = "JFIF",'\0' - writeByte(1); // versionhi - writeByte(1); // versionlo - writeByte(0); // xyunits - writeWord(1); // xdensity - writeWord(1); // ydensity - writeByte(0); // thumbnwidth - writeByte(0); // thumbnheight - } - - function writeSOF0(width, height) - { - writeWord(0xFFC0); // marker - writeWord(17); // length, truecolor YUV JPG - writeByte(8); // precision - writeWord(height); - writeWord(width); - writeByte(3); // nrofcomponents - writeByte(1); // IdY - writeByte(0x11); // HVY - writeByte(0); // QTY - writeByte(2); // IdU - writeByte(0x11); // HVU - writeByte(1); // QTU - writeByte(3); // IdV - writeByte(0x11); // HVV - writeByte(1); // QTV - } - - function writeDQT() - { - writeWord(0xFFDB); // marker - writeWord(132); // length - writeByte(0); - for (var i=0; i<64; i++) { - writeByte(YTable[i]); - } - writeByte(1); - for (var j=0; j<64; j++) { - writeByte(UVTable[j]); - } - } - - function writeDHT() - { - writeWord(0xFFC4); // marker - writeWord(0x01A2); // length - - writeByte(0); // HTYDCinfo - for (var i=0; i<16; i++) { - writeByte(std_dc_luminance_nrcodes[i+1]); - } - for (var j=0; j<=11; j++) { - writeByte(std_dc_luminance_values[j]); - } - - writeByte(0x10); // HTYACinfo - for (var k=0; k<16; k++) { - writeByte(std_ac_luminance_nrcodes[k+1]); - } - for (var l=0; l<=161; l++) { - writeByte(std_ac_luminance_values[l]); - } - - writeByte(1); // HTUDCinfo - for (var m=0; m<16; m++) { - writeByte(std_dc_chrominance_nrcodes[m+1]); - } - for (var n=0; n<=11; n++) { - writeByte(std_dc_chrominance_values[n]); - } - - writeByte(0x11); // HTUACinfo - for (var o=0; o<16; o++) { - writeByte(std_ac_chrominance_nrcodes[o+1]); - } - for (var p=0; p<=161; p++) { - writeByte(std_ac_chrominance_values[p]); - } - } - - function writeSOS() - { - writeWord(0xFFDA); // marker - writeWord(12); // length - writeByte(3); // nrofcomponents - writeByte(1); // IdY - writeByte(0); // HTY - writeByte(2); // IdU - writeByte(0x11); // HTU - writeByte(3); // IdV - writeByte(0x11); // HTV - writeByte(0); // Ss - writeByte(0x3f); // Se - writeByte(0); // Bf - } - - function processDU(CDU, fdtbl, DC, HTDC, HTAC){ - var EOB = HTAC[0x00]; - var M16zeroes = HTAC[0xF0]; - var pos; - var I16 = 16; - var I63 = 63; - var I64 = 64; - var DU_DCT = fDCTQuant(CDU, fdtbl); - //ZigZag reorder - for (var j=0;j<I64;++j) { - DU[ZigZag[j]]=DU_DCT[j]; - } - var Diff = DU[0] - DC; DC = DU[0]; - //Encode DC - if (Diff==0) { - writeBits(HTDC[0]); // Diff might be 0 - } else { - pos = 32767+Diff; - writeBits(HTDC[category[pos]]); - writeBits(bitcode[pos]); - } - //Encode ACs - var end0pos = 63; // was const... which is crazy - for (; (end0pos>0)&&(DU[end0pos]==0); end0pos--) {}; - //end0pos = first element in reverse order !=0 - if ( end0pos == 0) { - writeBits(EOB); - return DC; - } - var i = 1; - var lng; - while ( i <= end0pos ) { - var startpos = i; - for (; (DU[i]==0) && (i<=end0pos); ++i) {} - var nrzeroes = i-startpos; - if ( nrzeroes >= I16 ) { - lng = nrzeroes>>4; - for (var nrmarker=1; nrmarker <= lng; ++nrmarker) - writeBits(M16zeroes); - nrzeroes = nrzeroes&0xF; - } - pos = 32767+DU[i]; - writeBits(HTAC[(nrzeroes<<4)+category[pos]]); - writeBits(bitcode[pos]); - i++; - } - if ( end0pos != I63 ) { - writeBits(EOB); - } - return DC; - } - - function initCharLookupTable(){ - var sfcc = String.fromCharCode; - for(var i=0; i < 256; i++){ ///// ACHTUNG // 255 - clt[i] = sfcc(i); - } - } - - this.encode = function(image,quality) // image data object - { - // var time_start = new Date().getTime(); - - if(quality) setQuality(quality); - - // Initialize bit writer - byteout = new Array(); - bytenew=0; - bytepos=7; - - // Add JPEG headers - writeWord(0xFFD8); // SOI - writeAPP0(); - writeDQT(); - writeSOF0(image.width,image.height); - writeDHT(); - writeSOS(); - - - // Encode 8x8 macroblocks - var DCY=0; - var DCU=0; - var DCV=0; - - bytenew=0; - bytepos=7; - - - this.encode.displayName = "_encode_"; - - var imageData = image.data; - var width = image.width; - var height = image.height; - - var quadWidth = width*4; - var tripleWidth = width*3; - - var x, y = 0; - var r, g, b; - var start,p, col,row,pos; - while(y < height){ - x = 0; - while(x < quadWidth){ - start = quadWidth * y + x; - p = start; - col = -1; - row = 0; - - for(pos=0; pos < 64; pos++){ - row = pos >> 3;// /8 - col = ( pos & 7 ) * 4; // %8 - p = start + ( row * quadWidth ) + col; - - if(y+row >= height){ // padding bottom - p-= (quadWidth*(y+1+row-height)); - } - - if(x+col >= quadWidth){ // padding right - p-= ((x+col) - quadWidth +4) - } - - r = imageData[ p++ ]; - g = imageData[ p++ ]; - b = imageData[ p++ ]; - - - /* // calculate YUV values dynamically - YDU[pos]=((( 0.29900)*r+( 0.58700)*g+( 0.11400)*b))-128; //-0x80 - UDU[pos]=(((-0.16874)*r+(-0.33126)*g+( 0.50000)*b)); - VDU[pos]=((( 0.50000)*r+(-0.41869)*g+(-0.08131)*b)); - */ - - // use lookup table (slightly faster) - YDU[pos] = ((RGB_YUV_TABLE[r] + RGB_YUV_TABLE[(g + 256)>>0] + RGB_YUV_TABLE[(b + 512)>>0]) >> 16)-128; - UDU[pos] = ((RGB_YUV_TABLE[(r + 768)>>0] + RGB_YUV_TABLE[(g + 1024)>>0] + RGB_YUV_TABLE[(b + 1280)>>0]) >> 16)-128; - VDU[pos] = ((RGB_YUV_TABLE[(r + 1280)>>0] + RGB_YUV_TABLE[(g + 1536)>>0] + RGB_YUV_TABLE[(b + 1792)>>0]) >> 16)-128; - - } - - DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT); - DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); - DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); - x+=32; - } - y+=8; - } - - - //////////////////////////////////////////////////////////////// - - // Do the bit alignment of the EOI marker - if ( bytepos >= 0 ) { - var fillbits = []; - fillbits[1] = bytepos+1; - fillbits[0] = (1<<(bytepos+1))-1; - writeBits(fillbits); - } - - writeWord(0xFFD9); //EOI - - var jpegDataUri = 'data:image/jpeg;base64,' + btoa(byteout.join('')); - - byteout = []; - - // benchmarking - // var duration = new Date().getTime() - time_start; - // console.log('Encoding time: '+ currentQuality + 'ms'); - // - - return jpegDataUri - } - - function setQuality(quality){ - if (quality <= 0) { - quality = 1; - } - if (quality > 100) { - quality = 100; - } - - if(currentQuality == quality) return // don't recalc if unchanged - - var sf = 0; - if (quality < 50) { - sf = Math.floor(5000 / quality); - } else { - sf = Math.floor(200 - quality*2); - } - - initQuantTables(sf); - currentQuality = quality; - // console.log('Quality set to: '+quality +'%'); - } - - function init(){ - // var time_start = new Date().getTime(); - if(!quality) quality = 50; - // Create tables - initCharLookupTable() - initHuffmanTbl(); - initCategoryNumber(); - initRGBYUVTable(); - - setQuality(quality); - // var duration = new Date().getTime() - time_start; - // console.log('Initialization '+ duration + 'ms'); - } - - init(); - - }; - - JPEGEncoder.encode = function( data, quality ) { - var encoder = new JPEGEncoder( quality ); - - return encoder.encode( data ); - } - - return JPEGEncoder; - }); - /** - * @fileOverview Fix android canvas.toDataUrl bug. - */ - define('runtime/html5/androidpatch',[ - 'runtime/html5/util', - 'runtime/html5/jpegencoder', - 'base' - ], function( Util, encoder, Base ) { - var origin = Util.canvasToDataUrl, - supportJpeg; - - Util.canvasToDataUrl = function( canvas, type, quality ) { - var ctx, w, h, fragement, parts; - - // 闈瀉ndroid鎵嬫満鐩存帴璺宠繃銆� - if ( !Base.os.android ) { - return origin.apply( null, arguments ); - } - - // 妫�娴嬫槸鍚anvas鏀寔jpeg瀵煎嚭锛屾牴鎹暟鎹牸寮忔潵鍒ゆ柇銆� - // JPEG 鍓嶄袱浣嶅垎鍒槸锛�255, 216 - if ( type === 'image/jpeg' && typeof supportJpeg === 'undefined' ) { - fragement = origin.apply( null, arguments ); - - parts = fragement.split(','); - - if ( ~parts[ 0 ].indexOf('base64') ) { - fragement = atob( parts[ 1 ] ); - } else { - fragement = decodeURIComponent( parts[ 1 ] ); - } - - fragement = fragement.substring( 0, 2 ); - - supportJpeg = fragement.charCodeAt( 0 ) === 255 && - fragement.charCodeAt( 1 ) === 216; - } - - // 鍙湁鍦╝ndroid鐜涓嬫墠淇 - if ( type === 'image/jpeg' && !supportJpeg ) { - w = canvas.width; - h = canvas.height; - ctx = canvas.getContext('2d'); - - return encoder.encode( ctx.getImageData( 0, 0, w, h ), quality ); - } - - return origin.apply( null, arguments ); - }; - }); - /** - * @fileOverview Image - */ - define('runtime/html5/image',[ - 'base', - 'runtime/html5/runtime', - 'runtime/html5/util' - ], function( Base, Html5Runtime, Util ) { - - var BLANK = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D'; - - return Html5Runtime.register( 'Image', { - - // flag: 鏍囪鏄惁琚慨鏀硅繃銆� - modified: false, - - init: function() { - var me = this, - img = new Image(); - - img.onload = function() { - - me._info = { - type: me.type, - width: this.width, - height: this.height - }; - - // 璇诲彇meta淇℃伅銆� - if ( !me._metas && 'image/jpeg' === me.type ) { - Util.parseMeta( me._blob, function( error, ret ) { - me._metas = ret; - me.owner.trigger('load'); - }); - } else { - me.owner.trigger('load'); - } - }; - - img.onerror = function() { - me.owner.trigger('error'); - }; - - me._img = img; - }, - - loadFromBlob: function( blob ) { - var me = this, - img = me._img; - - me._blob = blob; - me.type = blob.type; - img.src = Util.createObjectURL( blob.getSource() ); - me.owner.once( 'load', function() { - Util.revokeObjectURL( img.src ); - }); - }, - - resize: function( width, height ) { - var canvas = this._canvas || - (this._canvas = document.createElement('canvas')); - - this._resize( this._img, canvas, width, height ); - this._blob = null; // 娌$敤浜嗭紝鍙互鍒犳帀浜嗐�� - this.modified = true; - this.owner.trigger('complete'); - }, - - getAsBlob: function( type ) { - var blob = this._blob, - opts = this.options, - canvas; - - type = type || this.type; - - // blob闇�瑕侀噸鏂扮敓鎴愩�� - if ( this.modified || this.type !== type ) { - canvas = this._canvas; - - if ( type === 'image/jpeg' ) { - - blob = Util.canvasToDataUrl( canvas, 'image/jpeg', - opts.quality ); - - if ( opts.preserveHeaders && this._metas && - this._metas.imageHead ) { - - blob = Util.dataURL2ArrayBuffer( blob ); - blob = Util.updateImageHead( blob, - this._metas.imageHead ); - blob = Util.arrayBufferToBlob( blob, type ); - return blob; - } - } else { - blob = Util.canvasToDataUrl( canvas, type ); - } - - blob = Util.dataURL2Blob( blob ); - } - - return blob; - }, - - getAsDataUrl: function( type ) { - var opts = this.options; - - type = type || this.type; - - if ( type === 'image/jpeg' ) { - return Util.canvasToDataUrl( this._canvas, type, opts.quality ); - } else { - return this._canvas.toDataURL( type ); - } - }, - - getOrientation: function() { - return this._metas && this._metas.exif && - this._metas.exif.get('Orientation') || 1; - }, - - info: function( val ) { - - // setter - if ( val ) { - this._info = val; - return this; - } - - // getter - return this._info; - }, - - meta: function( val ) { - - // setter - if ( val ) { - this._meta = val; - return this; - } - - // getter - return this._meta; - }, - - destroy: function() { - var canvas = this._canvas; - this._img.onload = null; - - if ( canvas ) { - canvas.getContext('2d') - .clearRect( 0, 0, canvas.width, canvas.height ); - canvas.width = canvas.height = 0; - this._canvas = null; - } - - // 閲婃斁鍐呭瓨銆傞潪甯搁噸瑕侊紝鍚﹀垯閲婃斁涓嶄簡image鐨勫唴瀛樸�� - this._img.src = BLANK; - this._img = this._blob = null; - }, - - _resize: function( img, cvs, width, height ) { - var opts = this.options, - naturalWidth = img.width, - naturalHeight = img.height, - orientation = this.getOrientation(), - scale, w, h, x, y; - - // values that require 90 degree rotation - if ( ~[ 5, 6, 7, 8 ].indexOf( orientation ) ) { - - // 浜ゆ崲width, height鐨勫�笺�� - width ^= height; - height ^= width; - width ^= height; - } - - scale = Math[ opts.crop ? 'max' : 'min' ]( width / naturalWidth, - height / naturalHeight ); - - // 涓嶅厑璁告斁澶с�� - opts.allowMagnify || (scale = Math.min( 1, scale )); - - w = naturalWidth * scale; - h = naturalHeight * scale; - - if ( opts.crop ) { - cvs.width = width; - cvs.height = height; - } else { - cvs.width = w; - cvs.height = h; - } - - x = (cvs.width - w) / 2; - y = (cvs.height - h) / 2; - - opts.preserveHeaders || this._rotate2Orientaion( cvs, orientation ); - - this._renderImageToCanvas( cvs, img, x, y, w, h ); - }, - - _rotate2Orientaion: function( canvas, orientation ) { - var width = canvas.width, - height = canvas.height, - ctx = canvas.getContext('2d'); - - switch ( orientation ) { - case 5: - case 6: - case 7: - case 8: - canvas.width = height; - canvas.height = width; - break; - } - - switch ( orientation ) { - case 2: // horizontal flip - ctx.translate( width, 0 ); - ctx.scale( -1, 1 ); - break; - - case 3: // 180 rotate left - ctx.translate( width, height ); - ctx.rotate( Math.PI ); - break; - - case 4: // vertical flip - ctx.translate( 0, height ); - ctx.scale( 1, -1 ); - break; - - case 5: // vertical flip + 90 rotate right - ctx.rotate( 0.5 * Math.PI ); - ctx.scale( 1, -1 ); - break; - - case 6: // 90 rotate right - ctx.rotate( 0.5 * Math.PI ); - ctx.translate( 0, -height ); - break; - - case 7: // horizontal flip + 90 rotate right - ctx.rotate( 0.5 * Math.PI ); - ctx.translate( width, -height ); - ctx.scale( -1, 1 ); - break; - - case 8: // 90 rotate left - ctx.rotate( -0.5 * Math.PI ); - ctx.translate( -width, 0 ); - break; - } - }, - - // https://github.com/stomita/ios-imagefile-megapixel/ - // blob/master/src/megapix-image.js - _renderImageToCanvas: (function() { - - // 濡傛灉涓嶆槸ios, 涓嶉渶瑕佽繖涔堝鏉傦紒 - if ( !Base.os.ios ) { - return function( canvas, img, x, y, w, h ) { - canvas.getContext('2d').drawImage( img, x, y, w, h ); - }; - } - - /** - * Detecting vertical squash in loaded image. - * Fixes a bug which squash image vertically while drawing into - * canvas for some images. - */ - function detectVerticalSquash( img, iw, ih ) { - var canvas = document.createElement('canvas'), - ctx = canvas.getContext('2d'), - sy = 0, - ey = ih, - py = ih, - data, alpha, ratio; - - - canvas.width = 1; - canvas.height = ih; - ctx.drawImage( img, 0, 0 ); - data = ctx.getImageData( 0, 0, 1, ih ).data; - - // search image edge pixel position in case - // it is squashed vertically. - while ( py > sy ) { - alpha = data[ (py - 1) * 4 + 3 ]; - - if ( alpha === 0 ) { - ey = py; - } else { - sy = py; - } - - py = (ey + sy) >> 1; - } - - ratio = (py / ih); - return (ratio === 0) ? 1 : ratio; - } - - // fix ie7 bug - // http://stackoverflow.com/questions/11929099/ - // html5-canvas-drawimage-ratio-bug-ios - if ( Base.os.ios >= 7 ) { - return function( canvas, img, x, y, w, h ) { - var iw = img.naturalWidth, - ih = img.naturalHeight, - vertSquashRatio = detectVerticalSquash( img, iw, ih ); - - return canvas.getContext('2d').drawImage( img, 0, 0, - iw * vertSquashRatio, ih * vertSquashRatio, - x, y, w, h ); - }; - } - - /** - * Detect subsampling in loaded image. - * In iOS, larger images than 2M pixels may be - * subsampled in rendering. - */ - function detectSubsampling( img ) { - var iw = img.naturalWidth, - ih = img.naturalHeight, - canvas, ctx; - - // subsampling may happen overmegapixel image - if ( iw * ih > 1024 * 1024 ) { - canvas = document.createElement('canvas'); - canvas.width = canvas.height = 1; - ctx = canvas.getContext('2d'); - ctx.drawImage( img, -iw + 1, 0 ); - - // subsampled image becomes half smaller in rendering size. - // check alpha channel value to confirm image is covering - // edge pixel or not. if alpha value is 0 - // image is not covering, hence subsampled. - return ctx.getImageData( 0, 0, 1, 1 ).data[ 3 ] === 0; - } else { - return false; - } - } - - - return function( canvas, img, x, y, width, height ) { - var iw = img.naturalWidth, - ih = img.naturalHeight, - ctx = canvas.getContext('2d'), - subsampled = detectSubsampling( img ), - doSquash = this.type === 'image/jpeg', - d = 1024, - sy = 0, - dy = 0, - tmpCanvas, tmpCtx, vertSquashRatio, dw, dh, sx, dx; - - if ( subsampled ) { - iw /= 2; - ih /= 2; - } - - ctx.save(); - tmpCanvas = document.createElement('canvas'); - tmpCanvas.width = tmpCanvas.height = d; - - tmpCtx = tmpCanvas.getContext('2d'); - vertSquashRatio = doSquash ? - detectVerticalSquash( img, iw, ih ) : 1; - - dw = Math.ceil( d * width / iw ); - dh = Math.ceil( d * height / ih / vertSquashRatio ); - - while ( sy < ih ) { - sx = 0; - dx = 0; - while ( sx < iw ) { - tmpCtx.clearRect( 0, 0, d, d ); - tmpCtx.drawImage( img, -sx, -sy ); - ctx.drawImage( tmpCanvas, 0, 0, d, d, - x + dx, y + dy, dw, dh ); - sx += d; - dx += dw; - } - sy += d; - dy += dh; - } - ctx.restore(); - tmpCanvas = tmpCtx = null; - }; - })() - }); - }); - /** - * @fileOverview Transport - * @todo 鏀寔chunked浼犺緭锛屼紭鍔匡細 - * 鍙互灏嗗ぇ鏂囦欢鍒嗘垚灏忓潡锛屾尐涓紶杈擄紝鍙互鎻愰珮澶ф枃浠舵垚鍔熺巼锛屽綋澶辫触鐨勬椂鍊欙紝涔熷彧闇�瑕侀噸浼犻偅灏忛儴鍒嗭紝 - * 鑰屼笉闇�瑕侀噸澶村啀浼犱竴娆°�傚彟澶栨柇鐐圭画浼犱篃闇�瑕佺敤chunked鏂瑰紡銆� - */ - define('runtime/html5/transport',[ - 'base', - 'runtime/html5/runtime' - ], function( Base, Html5Runtime ) { - - var noop = Base.noop, - $ = Base.$; - - return Html5Runtime.register( 'Transport', { - init: function() { - this._status = 0; - this._response = null; - }, - - send: function() { - var owner = this.owner, - opts = this.options, - xhr = this._initAjax(), - blob = owner._blob, - server = opts.server, - formData, binary, fr; - - if ( opts.sendAsBinary ) { - server += (/\?/.test( server ) ? '&' : '?') + - $.param( owner._formData ); - - binary = blob.getSource(); - } else { - formData = new FormData(); - $.each( owner._formData, function( k, v ) { - formData.append( k, v ); - }); - - formData.append( opts.fileVal, blob.getSource(), - opts.filename || owner._formData.name || '' ); - } - - if ( opts.withCredentials && 'withCredentials' in xhr ) { - xhr.open( opts.method, server, true ); - xhr.withCredentials = true; - } else { - xhr.open( opts.method, server ); - } - - this._setRequestHeader( xhr, opts.headers ); - - if ( binary ) { - xhr.overrideMimeType('application/octet-stream'); - - // android鐩存帴鍙戦�乥lob浼氬鑷存湇鍔$鎺ユ敹鍒扮殑鏄┖鏂囦欢銆� - // bug璇︽儏銆� - // https://code.google.com/p/android/issues/detail?id=39882 - // 鎵�浠ュ厛鐢╢ileReader璇诲彇鍑烘潵鍐嶉�氳繃arraybuffer鐨勬柟寮忓彂閫併�� - if ( Base.os.android ) { - fr = new FileReader(); - - fr.onload = function() { - xhr.send( this.result ); - fr = fr.onload = null; - }; - - fr.readAsArrayBuffer( binary ); - } else { - xhr.send( binary ); - } - } else { - xhr.send( formData ); - } - }, - - getResponse: function() { - return this._response; - }, - - getResponseAsJson: function() { - return this._parseJson( this._response ); - }, - - getStatus: function() { - return this._status; - }, - - abort: function() { - var xhr = this._xhr; - - if ( xhr ) { - xhr.upload.onprogress = noop; - xhr.onreadystatechange = noop; - xhr.abort(); - - this._xhr = xhr = null; - } - }, - - destroy: function() { - this.abort(); - }, - - _initAjax: function() { - var me = this, - xhr = new XMLHttpRequest(), - opts = this.options; - - if ( opts.withCredentials && !('withCredentials' in xhr) && - typeof XDomainRequest !== 'undefined' ) { - xhr = new XDomainRequest(); - } - - xhr.upload.onprogress = function( e ) { - var percentage = 0; - - if ( e.lengthComputable ) { - percentage = e.loaded / e.total; - } - - return me.trigger( 'progress', percentage ); - }; - - xhr.onreadystatechange = function() { - - if ( xhr.readyState !== 4 ) { - return; - } - - xhr.upload.onprogress = noop; - xhr.onreadystatechange = noop; - me._xhr = null; - me._status = xhr.status; - - if ( xhr.status >= 200 && xhr.status < 300 ) { - me._response = xhr.responseText; - return me.trigger('load'); - } else if ( xhr.status >= 500 && xhr.status < 600 ) { - me._response = xhr.responseText; - return me.trigger( 'error', 'server' ); - } - - - return me.trigger( 'error', me._status ? 'http' : 'abort' ); - }; - - me._xhr = xhr; - return xhr; - }, - - _setRequestHeader: function( xhr, headers ) { - $.each( headers, function( key, val ) { - xhr.setRequestHeader( key, val ); - }); - }, - - _parseJson: function( str ) { - var json; - - try { - json = JSON.parse( str ); - } catch ( ex ) { - json = {}; - } - - return json; - } - }); - }); - /** - * @fileOverview FlashRuntime - */ - define('runtime/flash/runtime',[ - 'base', - 'runtime/runtime', - 'runtime/compbase' - ], function( Base, Runtime, CompBase ) { - - var $ = Base.$, - type = 'flash', - components = {}; - - - function getFlashVersion() { - var version; - - try { - version = navigator.plugins[ 'Shockwave Flash' ]; - version = version.description; - } catch ( ex ) { - try { - version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash') - .GetVariable('$version'); - } catch ( ex2 ) { - version = '0.0'; - } - } - version = version.match( /\d+/g ); - return parseFloat( version[ 0 ] + '.' + version[ 1 ], 10 ); - } - - function FlashRuntime() { - var pool = {}, - clients = {}, - destory = this.destory, - me = this, - jsreciver = Base.guid('webuploader_'); - - Runtime.apply( me, arguments ); - me.type = type; - - - // 杩欎釜鏂规硶鐨勮皟鐢ㄨ�咃紝瀹為檯涓婃槸RuntimeClient - me.exec = function( comp, fn/*, args...*/ ) { - var client = this, - uid = client.uid, - args = Base.slice( arguments, 2 ), - instance; - - clients[ uid ] = client; - - if ( components[ comp ] ) { - if ( !pool[ uid ] ) { - pool[ uid ] = new components[ comp ]( client, me ); - } - - instance = pool[ uid ]; - - if ( instance[ fn ] ) { - return instance[ fn ].apply( instance, args ); - } - } - - return me.flashExec.apply( client, arguments ); - }; - - function handler( evt, obj ) { - var type = evt.type || evt, - parts, uid; - - parts = type.split('::'); - uid = parts[ 0 ]; - type = parts[ 1 ]; - - // console.log.apply( console, arguments ); - - if ( type === 'Ready' && uid === me.uid ) { - me.trigger('ready'); - } else if ( clients[ uid ] ) { - clients[ uid ].trigger( type.toLowerCase(), evt, obj ); - } - - // Base.log( evt, obj ); - } - - // flash鐨勬帴鍙楀櫒銆� - window[ jsreciver ] = function() { - var args = arguments; - - // 涓轰簡鑳芥崟鑾峰緱鍒般�� - setTimeout(function() { - handler.apply( null, args ); - }, 1 ); - }; - - this.jsreciver = jsreciver; - - this.destory = function() { - // @todo 鍒犻櫎姹犲瓙涓殑鎵�鏈夊疄渚� - return destory && destory.apply( this, arguments ); - }; - - this.flashExec = function( comp, fn ) { - var flash = me.getFlash(), - args = Base.slice( arguments, 2 ); - - return flash.exec( this.uid, comp, fn, args ); - }; - - // @todo - } - - Base.inherits( Runtime, { - constructor: FlashRuntime, - - init: function() { - var container = this.getContainer(), - opts = this.options, - html; - - // if not the minimal height, shims are not initialized - // in older browsers (e.g FF3.6, IE6,7,8, Safari 4.0,5.0, etc) - container.css({ - position: 'absolute', - top: '-8px', - left: '-8px', - width: '9px', - height: '9px', - overflow: 'hidden' - }); - - // insert flash object - html = '<object id="' + this.uid + '" type="application/' + - 'x-shockwave-flash" data="' + opts.swf + '" '; - - if ( Base.browser.ie ) { - html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '; - } - - html += 'width="100%" height="100%" style="outline:0">' + - '<param name="movie" value="' + opts.swf + '" />' + - '<param name="flashvars" value="uid=' + this.uid + - '&jsreciver=' + this.jsreciver + '" />' + - '<param name="wmode" value="transparent" />' + - '<param name="allowscriptaccess" value="always" />' + - '</object>'; - - container.html( html ); - }, - - getFlash: function() { - if ( this._flash ) { - return this._flash; - } - - this._flash = $( '#' + this.uid ).get( 0 ); - return this._flash; - } - - }); - - FlashRuntime.register = function( name, component ) { - component = components[ name ] = Base.inherits( CompBase, $.extend({ - - // @todo fix this later - flashExec: function() { - var owner = this.owner, - runtime = this.getRuntime(); - - return runtime.flashExec.apply( owner, arguments ); - } - }, component ) ); - - return component; - }; - - if ( getFlashVersion() >= 11.4 ) { - Runtime.addRuntime( type, FlashRuntime ); - } - - return FlashRuntime; - }); - /** - * @fileOverview FilePicker - */ - define('runtime/flash/filepicker',[ - 'base', - 'runtime/flash/runtime' - ], function( Base, FlashRuntime ) { - var $ = Base.$; - - return FlashRuntime.register( 'FilePicker', { - init: function( opts ) { - var copy = $.extend({}, opts ), - len, i; - - // 淇Flash鍐嶆病鏈夎缃畉itle鐨勬儏鍐典笅鏃犳硶寮瑰嚭flash鏂囦欢閫夋嫨妗嗙殑bug. - len = copy.accept && copy.accept.length; - for ( i = 0; i < len; i++ ) { - if ( !copy.accept[ i ].title ) { - copy.accept[ i ].title = 'Files'; - } - } - - delete copy.button; - delete copy.container; - - this.flashExec( 'FilePicker', 'init', copy ); - }, - - destroy: function() { - // todo - } - }); - }); - /** - * @fileOverview 鍥剧墖鍘嬬缉 - */ - define('runtime/flash/image',[ - 'runtime/flash/runtime' - ], function( FlashRuntime ) { - - return FlashRuntime.register( 'Image', { - // init: function( options ) { - // var owner = this.owner; - - // this.flashExec( 'Image', 'init', options ); - // owner.on( 'load', function() { - // debugger; - // }); - // }, - - loadFromBlob: function( blob ) { - var owner = this.owner; - - owner.info() && this.flashExec( 'Image', 'info', owner.info() ); - owner.meta() && this.flashExec( 'Image', 'meta', owner.meta() ); - - this.flashExec( 'Image', 'loadFromBlob', blob.uid ); - } - }); - }); - /** - * @fileOverview Transport flash瀹炵幇 - */ - define('runtime/flash/transport',[ - 'base', - 'runtime/flash/runtime', - 'runtime/client' - ], function( Base, FlashRuntime, RuntimeClient ) { - var $ = Base.$; - - return FlashRuntime.register( 'Transport', { - init: function() { - this._status = 0; - this._response = null; - this._responseJson = null; - }, - - send: function() { - var owner = this.owner, - opts = this.options, - xhr = this._initAjax(), - blob = owner._blob, - server = opts.server, - binary; - - xhr.connectRuntime( blob.ruid ); - - if ( opts.sendAsBinary ) { - server += (/\?/.test( server ) ? '&' : '?') + - $.param( owner._formData ); - - binary = blob.uid; - } else { - $.each( owner._formData, function( k, v ) { - xhr.exec( 'append', k, v ); - }); - - xhr.exec( 'appendBlob', opts.fileVal, blob.uid, - opts.filename || owner._formData.name || '' ); - } - - this._setRequestHeader( xhr, opts.headers ); - xhr.exec( 'send', { - method: opts.method, - url: server - }, binary ); - }, - - getStatus: function() { - return this._status; - }, - - getResponse: function() { - return this._response; - }, - - getResponseAsJson: function() { - return this._responseJson; - }, - - abort: function() { - var xhr = this._xhr; - - if ( xhr ) { - xhr.exec('abort'); - xhr.destroy(); - this._xhr = xhr = null; - } - }, - - destroy: function() { - this.abort(); - }, - - _initAjax: function() { - var me = this, - xhr = new RuntimeClient('XMLHttpRequest'); - - xhr.on( 'uploadprogress progress', function( e ) { - return me.trigger( 'progress', e.loaded / e.total ); - }); - - xhr.on( 'load', function() { - var status = xhr.exec('getStatus'), - err = ''; - - xhr.off(); - me._xhr = null; - - if ( status >= 200 && status < 300 ) { - me._response = xhr.exec('getResponse'); - me._responseJson = xhr.exec('getResponseAsJson'); - } else if ( status >= 500 && status < 600 ) { - me._response = xhr.exec('getResponse'); - me._responseJson = xhr.exec('getResponseAsJson'); - err = 'server'; - } else { - err = 'http'; - } - - xhr.destroy(); - xhr = null; - - return err ? me.trigger( 'error', err ) : me.trigger('load'); - }); - - xhr.on( 'error', function() { - xhr.off(); - me._xhr = null; - me.trigger( 'error', 'http' ); - }); - - me._xhr = xhr; - return xhr; - }, - - _setRequestHeader: function( xhr, headers ) { - $.each( headers, function( key, val ) { - xhr.exec( 'setRequestHeader', key, val ); - }); - } - }); - }); - /** - * @fileOverview 瀹屽叏鐗堟湰銆� - */ - define('preset/all',[ - 'base', - - // widgets - 'widgets/filednd', - 'widgets/filepaste', - 'widgets/filepicker', - 'widgets/image', - 'widgets/queue', - 'widgets/runtime', - 'widgets/upload', - 'widgets/validator', - - // runtimes - // html5 - 'runtime/html5/blob', - 'runtime/html5/dnd', - 'runtime/html5/filepaste', - 'runtime/html5/filepicker', - 'runtime/html5/imagemeta/exif', - 'runtime/html5/androidpatch', - 'runtime/html5/image', - 'runtime/html5/transport', - - // flash - 'runtime/flash/filepicker', - 'runtime/flash/image', - 'runtime/flash/transport' - ], function( Base ) { - return Base; - }); - define('webuploader',[ - 'preset/all' - ], function( preset ) { - return preset; - }); - return require('webuploader'); -}); +/*! WebUploader 0.1.2 */ + + +/** + * @fileOverview 璁╁唴閮ㄥ悇涓儴浠剁殑浠g爜鍙互鐢╗amd](https://github.com/amdjs/amdjs-api/wiki/AMD)妯″潡瀹氫箟鏂瑰紡缁勭粐璧锋潵銆� + * + * AMD API 鍐呴儴鐨勭畝鍗曚笉瀹屽叏瀹炵幇锛岃蹇界暐銆傚彧鏈夊綋WebUploader琚悎骞舵垚涓�涓枃浠剁殑鏃跺�欐墠浼氬紩鍏ャ�� + */ +(function( root, factory ) { + var modules = {}, + + // 鍐呴儴require, 绠�鍗曚笉瀹屽叏瀹炵幇銆� + // https://github.com/amdjs/amdjs-api/wiki/require + _require = function( deps, callback ) { + var args, len, i; + + // 濡傛灉deps涓嶆槸鏁扮粍锛屽垯鐩存帴杩斿洖鎸囧畾module + if ( typeof deps === 'string' ) { + return getModule( deps ); + } else { + args = []; + for( len = deps.length, i = 0; i < len; i++ ) { + args.push( getModule( deps[ i ] ) ); + } + + return callback.apply( null, args ); + } + }, + + // 鍐呴儴define锛屾殏鏃朵笉鏀寔涓嶆寚瀹歩d. + _define = function( id, deps, factory ) { + if ( arguments.length === 2 ) { + factory = deps; + deps = null; + } + + _require( deps || [], function() { + setModule( id, factory, arguments ); + }); + }, + + // 璁剧疆module, 鍏煎CommonJs鍐欐硶銆� + setModule = function( id, factory, args ) { + var module = { + exports: factory + }, + returned; + + if ( typeof factory === 'function' ) { + args.length || (args = [ _require, module.exports, module ]); + returned = factory.apply( null, args ); + returned !== undefined && (module.exports = returned); + } + + modules[ id ] = module.exports; + }, + + // 鏍规嵁id鑾峰彇module + getModule = function( id ) { + var module = modules[ id ] || root[ id ]; + + if ( !module ) { + throw new Error( '`' + id + '` is undefined' ); + } + + return module; + }, + + // 灏嗘墍鏈塵odules锛屽皢璺緞ids瑁呮崲鎴愬璞°�� + exportsTo = function( obj ) { + var key, host, parts, part, last, ucFirst; + + // make the first character upper case. + ucFirst = function( str ) { + return str && (str.charAt( 0 ).toUpperCase() + str.substr( 1 )); + }; + + for ( key in modules ) { + host = obj; + + if ( !modules.hasOwnProperty( key ) ) { + continue; + } + + parts = key.split('/'); + last = ucFirst( parts.pop() ); + + while( (part = ucFirst( parts.shift() )) ) { + host[ part ] = host[ part ] || {}; + host = host[ part ]; + } + + host[ last ] = modules[ key ]; + } + }, + + exports = factory( root, _define, _require ), + origin; + + // exports every module. + exportsTo( exports ); + + if ( typeof module === 'object' && typeof module.exports === 'object' ) { + + // For CommonJS and CommonJS-like environments where a proper window is present, + module.exports = exports; + } else if ( typeof define === 'function' && define.amd ) { + + // Allow using this built library as an AMD module + // in another project. That other project will only + // see this AMD call, not the internal modules in + // the closure below. + define([], exports ); + } else { + + // Browser globals case. Just assign the + // result to a property on the global. + origin = root.WebUploader; + root.WebUploader = exports; + root.WebUploader.noConflict = function() { + root.WebUploader = origin; + }; + } +})( this, function( window, define, require ) { + + + /** + * @fileOverview jQuery or Zepto + */ + define('dollar-third',[],function() { + return window.jQuery || window.Zepto; + }); + /** + * @fileOverview Dom 鎿嶄綔鐩稿叧 + */ + define('dollar',[ + 'dollar-third' + ], function( _ ) { + return _; + }); + /** + * @fileOverview 浣跨敤jQuery鐨凱romise + */ + define('promise-third',[ + 'dollar' + ], function( $ ) { + return { + Deferred: $.Deferred, + when: $.when, + + isPromise: function( anything ) { + return anything && typeof anything.then === 'function'; + } + }; + }); + /** + * @fileOverview Promise/A+ + */ + define('promise',[ + 'promise-third' + ], function( _ ) { + return _; + }); + /** + * @fileOverview 鍩虹绫绘柟娉曘�� + */ + + /** + * Web Uploader鍐呴儴绫荤殑璇︾粏璇存槑锛屼互涓嬫彁鍙婄殑鍔熻兘绫伙紝閮藉彲浠ュ湪`WebUploader`杩欎釜鍙橀噺涓闂埌銆� + * + * As you know, Web Uploader鐨勬瘡涓枃浠堕兘鏄敤杩嘯AMD](https://github.com/amdjs/amdjs-api/wiki/AMD)瑙勮寖涓殑`define`缁勭粐璧锋潵鐨�, 姣忎釜Module閮戒細鏈変釜module id. + * 榛樿module id璇ユ枃浠剁殑璺緞锛岃�屾璺緞灏嗕細杞寲鎴愬悕瀛楃┖闂村瓨鏀惧湪WebUploader涓�傚锛� + * + * * module `base`锛歐ebUploader.Base + * * module `file`: WebUploader.File + * * module `lib/dnd`: WebUploader.Lib.Dnd + * * module `runtime/html5/dnd`: WebUploader.Runtime.Html5.Dnd + * + * + * 浠ヤ笅鏂囨。灏嗗彲鑳界渷鐣WebUploader`鍓嶇紑銆� + * @module WebUploader + * @title WebUploader API鏂囨。 + */ + define('base',[ + 'dollar', + 'promise' + ], function( $, promise ) { + + var noop = function() {}, + call = Function.call; + + // http://jsperf.com/uncurrythis + // 鍙嶇閲屽寲 + function uncurryThis( fn ) { + return function() { + return call.apply( fn, arguments ); + }; + } + + function bindFn( fn, context ) { + return function() { + return fn.apply( context, arguments ); + }; + } + + function createObject( proto ) { + var f; + + if ( Object.create ) { + return Object.create( proto ); + } else { + f = function() {}; + f.prototype = proto; + return new f(); + } + } + + + /** + * 鍩虹绫伙紝鎻愪緵涓�浜涚畝鍗曞父鐢ㄧ殑鏂规硶銆� + * @class Base + */ + return { + + /** + * @property {String} version 褰撳墠鐗堟湰鍙枫�� + */ + version: '0.1.2', + + /** + * @property {jQuery|Zepto} $ 寮曠敤渚濊禆鐨刯Query鎴栬�匷epto瀵硅薄銆� + */ + $: $, + + Deferred: promise.Deferred, + + isPromise: promise.isPromise, + + when: promise.when, + + /** + * @description 绠�鍗曠殑娴忚鍣ㄦ鏌ョ粨鏋溿�� + * + * * `webkit` webkit鐗堟湰鍙凤紝濡傛灉娴忚鍣ㄤ负闈瀢ebkit鍐呮牳锛屾灞炴�т负`undefined`銆� + * * `chrome` chrome娴忚鍣ㄧ増鏈彿锛屽鏋滄祻瑙堝櫒涓篶hrome锛屾灞炴�т负`undefined`銆� + * * `ie` ie娴忚鍣ㄧ増鏈彿锛屽鏋滄祻瑙堝櫒涓洪潪ie锛屾灞炴�т负`undefined`銆�**鏆備笉鏀寔ie10+** + * * `firefox` firefox娴忚鍣ㄧ増鏈彿锛屽鏋滄祻瑙堝櫒涓洪潪firefox锛屾灞炴�т负`undefined`銆� + * * `safari` safari娴忚鍣ㄧ増鏈彿锛屽鏋滄祻瑙堝櫒涓洪潪safari锛屾灞炴�т负`undefined`銆� + * * `opera` opera娴忚鍣ㄧ増鏈彿锛屽鏋滄祻瑙堝櫒涓洪潪opera锛屾灞炴�т负`undefined`銆� + * + * @property {Object} [browser] + */ + browser: (function( ua ) { + var ret = {}, + webkit = ua.match( /WebKit\/([\d.]+)/ ), + chrome = ua.match( /Chrome\/([\d.]+)/ ) || + ua.match( /CriOS\/([\d.]+)/ ), + + ie = ua.match( /MSIE\s([\d\.]+)/ ) || + ua.match(/(?:trident)(?:.*rv:([\w.]+))?/i), + firefox = ua.match( /Firefox\/([\d.]+)/ ), + safari = ua.match( /Safari\/([\d.]+)/ ), + opera = ua.match( /OPR\/([\d.]+)/ ); + + webkit && (ret.webkit = parseFloat( webkit[ 1 ] )); + chrome && (ret.chrome = parseFloat( chrome[ 1 ] )); + ie && (ret.ie = parseFloat( ie[ 1 ] )); + firefox && (ret.firefox = parseFloat( firefox[ 1 ] )); + safari && (ret.safari = parseFloat( safari[ 1 ] )); + opera && (ret.opera = parseFloat( opera[ 1 ] )); + + return ret; + })( navigator.userAgent ), + + /** + * @description 鎿嶄綔绯荤粺妫�鏌ョ粨鏋溿�� + * + * * `android` 濡傛灉鍦╝ndroid娴忚鍣ㄧ幆澧冧笅锛屾鍊间负瀵瑰簲鐨刟ndroid鐗堟湰鍙凤紝鍚﹀垯涓篳undefined`銆� + * * `ios` 濡傛灉鍦╥os娴忚鍣ㄧ幆澧冧笅锛屾鍊间负瀵瑰簲鐨刬os鐗堟湰鍙凤紝鍚﹀垯涓篳undefined`銆� + * @property {Object} [os] + */ + os: (function( ua ) { + var ret = {}, + + // osx = !!ua.match( /\(Macintosh\; Intel / ), + android = ua.match( /(?:Android);?[\s\/]+([\d.]+)?/ ), + ios = ua.match( /(?:iPad|iPod|iPhone).*OS\s([\d_]+)/ ); + + // osx && (ret.osx = true); + android && (ret.android = parseFloat( android[ 1 ] )); + ios && (ret.ios = parseFloat( ios[ 1 ].replace( /_/g, '.' ) )); + + return ret; + })( navigator.userAgent ), + + /** + * 瀹炵幇绫讳笌绫讳箣闂寸殑缁ф壙銆� + * @method inherits + * @grammar Base.inherits( super ) => child + * @grammar Base.inherits( super, protos ) => child + * @grammar Base.inherits( super, protos, statics ) => child + * @param {Class} super 鐖剁被 + * @param {Object | Function} [protos] 瀛愮被鎴栬�呭璞°�傚鏋滃璞′腑鍖呭惈constructor锛屽瓙绫诲皢鏄敤姝ゅ睘鎬у�笺�� + * @param {Function} [protos.constructor] 瀛愮被鏋勯�犲櫒锛屼笉鎸囧畾鐨勮瘽灏嗗垱寤轰釜涓存椂鐨勭洿鎺ユ墽琛岀埗绫绘瀯閫犲櫒鐨勬柟娉曘�� + * @param {Object} [statics] 闈欐�佸睘鎬ф垨鏂规硶銆� + * @return {Class} 杩斿洖瀛愮被銆� + * @example + * function Person() { + * console.log( 'Super' ); + * } + * Person.prototype.hello = function() { + * console.log( 'hello' ); + * }; + * + * var Manager = Base.inherits( Person, { + * world: function() { + * console.log( 'World' ); + * } + * }); + * + * // 鍥犱负娌℃湁鎸囧畾鏋勯�犲櫒锛岀埗绫荤殑鏋勯�犲櫒灏嗕細鎵ц銆� + * var instance = new Manager(); // => Super + * + * // 缁ф壙瀛愮埗绫荤殑鏂规硶 + * instance.hello(); // => hello + * instance.world(); // => World + * + * // 瀛愮被鐨刜_super__灞炴�ф寚鍚戠埗绫� + * console.log( Manager.__super__ === Person ); // => true + */ + inherits: function( Super, protos, staticProtos ) { + var child; + + if ( typeof protos === 'function' ) { + child = protos; + protos = null; + } else if ( protos && protos.hasOwnProperty('constructor') ) { + child = protos.constructor; + } else { + child = function() { + return Super.apply( this, arguments ); + }; + } + + // 澶嶅埗闈欐�佹柟娉� + $.extend( true, child, Super, staticProtos || {} ); + + /* jshint camelcase: false */ + + // 璁╁瓙绫荤殑__super__灞炴�ф寚鍚戠埗绫汇�� + child.__super__ = Super.prototype; + + // 鏋勫缓鍘熷瀷锛屾坊鍔犲師鍨嬫柟娉曟垨灞炴�с�� + // 鏆傛椂鐢∣bject.create瀹炵幇銆� + child.prototype = createObject( Super.prototype ); + protos && $.extend( true, child.prototype, protos ); + + return child; + }, + + /** + * 涓�涓笉鍋氫换浣曚簨鎯呯殑鏂规硶銆傚彲浠ョ敤鏉ヨ祴鍊肩粰榛樿鐨刢allback. + * @method noop + */ + noop: noop, + + /** + * 杩斿洖涓�涓柊鐨勬柟娉曪紝姝ゆ柟娉曞皢宸叉寚瀹氱殑`context`鏉ユ墽琛屻�� + * @grammar Base.bindFn( fn, context ) => Function + * @method bindFn + * @example + * var doSomething = function() { + * console.log( this.name ); + * }, + * obj = { + * name: 'Object Name' + * }, + * aliasFn = Base.bind( doSomething, obj ); + * + * aliasFn(); // => Object Name + * + */ + bindFn: bindFn, + + /** + * 寮曠敤Console.log濡傛灉瀛樺湪鐨勮瘽锛屽惁鍒欏紩鐢ㄤ竴涓猍绌哄嚱鏁發oop](#WebUploader:Base.log)銆� + * @grammar Base.log( args... ) => undefined + * @method log + */ + log: (function() { + if ( window.console ) { + return bindFn( console.log, console ); + } + return noop; + })(), + + nextTick: (function() { + + return function( cb ) { + setTimeout( cb, 1 ); + }; + + // @bug 褰撴祻瑙堝櫒涓嶅湪褰撳墠绐楀彛鏃跺氨鍋滀簡銆� + // var next = window.requestAnimationFrame || + // window.webkitRequestAnimationFrame || + // window.mozRequestAnimationFrame || + // function( cb ) { + // window.setTimeout( cb, 1000 / 60 ); + // }; + + // // fix: Uncaught TypeError: Illegal invocation + // return bindFn( next, window ); + })(), + + /** + * 琚玔uncurrythis](http://www.2ality.com/2011/11/uncurrying-this.html)鐨勬暟缁剆lice鏂规硶銆� + * 灏嗙敤鏉ュ皢闈炴暟缁勫璞¤浆鍖栨垚鏁扮粍瀵硅薄銆� + * @grammar Base.slice( target, start[, end] ) => Array + * @method slice + * @example + * function doSomthing() { + * var args = Base.slice( arguments, 1 ); + * console.log( args ); + * } + * + * doSomthing( 'ignored', 'arg2', 'arg3' ); // => Array ["arg2", "arg3"] + */ + slice: uncurryThis( [].slice ), + + /** + * 鐢熸垚鍞竴鐨処D + * @method guid + * @grammar Base.guid() => String + * @grammar Base.guid( prefx ) => String + */ + guid: (function() { + var counter = 0; + + return function( prefix ) { + var guid = (+new Date()).toString( 32 ), + i = 0; + + for ( ; i < 5; i++ ) { + guid += Math.floor( Math.random() * 65535 ).toString( 32 ); + } + + return (prefix || 'wu_') + guid + (counter++).toString( 32 ); + }; + })(), + + /** + * 鏍煎紡鍖栨枃浠跺ぇ灏�, 杈撳嚭鎴愬甫鍗曚綅鐨勫瓧绗︿覆 + * @method formatSize + * @grammar Base.formatSize( size ) => String + * @grammar Base.formatSize( size, pointLength ) => String + * @grammar Base.formatSize( size, pointLength, units ) => String + * @param {Number} size 鏂囦欢澶у皬 + * @param {Number} [pointLength=2] 绮剧‘鍒扮殑灏忔暟鐐规暟銆� + * @param {Array} [units=[ 'B', 'K', 'M', 'G', 'TB' ]] 鍗曚綅鏁扮粍銆備粠瀛楄妭锛屽埌鍗冨瓧鑺傦紝涓�鐩村線涓婃寚瀹氥�傚鏋滃崟浣嶆暟缁勯噷闈㈠彧鎸囧畾浜嗗埌浜咾(鍗冨瓧鑺�)锛屽悓鏃舵枃浠跺ぇ灏忓ぇ浜嶮, 姝ゆ柟娉曠殑杈撳嚭灏嗚繕鏄樉绀烘垚澶氬皯K. + * @example + * console.log( Base.formatSize( 100 ) ); // => 100B + * console.log( Base.formatSize( 1024 ) ); // => 1.00K + * console.log( Base.formatSize( 1024, 0 ) ); // => 1K + * console.log( Base.formatSize( 1024 * 1024 ) ); // => 1.00M + * console.log( Base.formatSize( 1024 * 1024 * 1024 ) ); // => 1.00G + * console.log( Base.formatSize( 1024 * 1024 * 1024, 0, ['B', 'KB', 'MB'] ) ); // => 1024MB + */ + formatSize: function( size, pointLength, units ) { + var unit; + + units = units || [ 'B', 'K', 'M', 'G', 'TB' ]; + + while ( (unit = units.shift()) && size > 1024 ) { + size = size / 1024; + } + + return (unit === 'B' ? size : size.toFixed( pointLength || 2 )) + + unit; + } + }; + }); + /** + * 浜嬩欢澶勭悊绫伙紝鍙互鐙珛浣跨敤锛屼篃鍙互鎵╁睍缁欏璞′娇鐢ㄣ�� + * @fileOverview Mediator + */ + define('mediator',[ + 'base' + ], function( Base ) { + var $ = Base.$, + slice = [].slice, + separator = /\s+/, + protos; + + // 鏍规嵁鏉′欢杩囨护鍑轰簨浠秇andlers. + function findHandlers( arr, name, callback, context ) { + return $.grep( arr, function( handler ) { + return handler && + (!name || handler.e === name) && + (!callback || handler.cb === callback || + handler.cb._cb === callback) && + (!context || handler.ctx === context); + }); + } + + function eachEvent( events, callback, iterator ) { + // 涓嶆敮鎸佸璞★紝鍙敮鎸佸涓猠vent鐢ㄧ┖鏍奸殧寮� + $.each( (events || '').split( separator ), function( _, key ) { + iterator( key, callback ); + }); + } + + function triggerHanders( events, args ) { + var stoped = false, + i = -1, + len = events.length, + handler; + + while ( ++i < len ) { + handler = events[ i ]; + + if ( handler.cb.apply( handler.ctx2, args ) === false ) { + stoped = true; + break; + } + } + + return !stoped; + } + + protos = { + + /** + * 缁戝畾浜嬩欢銆� + * + * `callback`鏂规硶鍦ㄦ墽琛屾椂锛宎rguments灏嗕細鏉ユ簮浜巘rigger鐨勬椂鍊欐惡甯︾殑鍙傛暟銆傚 + * ```javascript + * var obj = {}; + * + * // 浣垮緱obj鏈変簨浠惰涓� + * Mediator.installTo( obj ); + * + * obj.on( 'testa', function( arg1, arg2 ) { + * console.log( arg1, arg2 ); // => 'arg1', 'arg2' + * }); + * + * obj.trigger( 'testa', 'arg1', 'arg2' ); + * ``` + * + * 濡傛灉`callback`涓紝鏌愪竴涓柟娉昤return false`浜嗭紝鍒欏悗缁殑鍏朵粬`callback`閮戒笉浼氳鎵ц鍒般�� + * 鍒囦細褰卞搷鍒癭trigger`鏂规硶鐨勮繑鍥炲�硷紝涓篳false`銆� + * + * `on`杩樺彲浠ョ敤鏉ユ坊鍔犱竴涓壒娈婁簨浠禶all`, 杩欐牱鎵�鏈夌殑浜嬩欢瑙﹀彂閮戒細鍝嶅簲鍒般�傚悓鏃舵绫籤callback`涓殑arguments鏈変竴涓笉鍚屽锛� + * 灏辨槸绗竴涓弬鏁颁负`type`锛岃褰曞綋鍓嶆槸浠�涔堜簨浠跺湪瑙﹀彂銆傛绫籤callback`鐨勪紭鍏堢骇姣旇剼浣庯紝浼氬啀姝e父`callback`鎵ц瀹屽悗瑙﹀彂銆� + * ```javascript + * obj.on( 'all', function( type, arg1, arg2 ) { + * console.log( type, arg1, arg2 ); // => 'testa', 'arg1', 'arg2' + * }); + * ``` + * + * @method on + * @grammar on( name, callback[, context] ) => self + * @param {String} name 浜嬩欢鍚嶏紝鏀寔澶氫釜浜嬩欢鐢ㄧ┖鏍奸殧寮� + * @param {Function} callback 浜嬩欢澶勭悊鍣� + * @param {Object} [context] 浜嬩欢澶勭悊鍣ㄧ殑涓婁笅鏂囥�� + * @return {self} 杩斿洖鑷韩锛屾柟渚块摼寮� + * @chainable + * @class Mediator + */ + on: function( name, callback, context ) { + var me = this, + set; + + if ( !callback ) { + return this; + } + + set = this._events || (this._events = []); + + eachEvent( name, callback, function( name, callback ) { + var handler = { e: name }; + + handler.cb = callback; + handler.ctx = context; + handler.ctx2 = context || me; + handler.id = set.length; + + set.push( handler ); + }); + + return this; + }, + + /** + * 缁戝畾浜嬩欢锛屼笖褰揾andler鎵ц瀹屽悗锛岃嚜鍔ㄨВ闄ょ粦瀹氥�� + * @method once + * @grammar once( name, callback[, context] ) => self + * @param {String} name 浜嬩欢鍚� + * @param {Function} callback 浜嬩欢澶勭悊鍣� + * @param {Object} [context] 浜嬩欢澶勭悊鍣ㄧ殑涓婁笅鏂囥�� + * @return {self} 杩斿洖鑷韩锛屾柟渚块摼寮� + * @chainable + */ + once: function( name, callback, context ) { + var me = this; + + if ( !callback ) { + return me; + } + + eachEvent( name, callback, function( name, callback ) { + var once = function() { + me.off( name, once ); + return callback.apply( context || me, arguments ); + }; + + once._cb = callback; + me.on( name, once, context ); + }); + + return me; + }, + + /** + * 瑙i櫎浜嬩欢缁戝畾 + * @method off + * @grammar off( [name[, callback[, context] ] ] ) => self + * @param {String} [name] 浜嬩欢鍚� + * @param {Function} [callback] 浜嬩欢澶勭悊鍣� + * @param {Object} [context] 浜嬩欢澶勭悊鍣ㄧ殑涓婁笅鏂囥�� + * @return {self} 杩斿洖鑷韩锛屾柟渚块摼寮� + * @chainable + */ + off: function( name, cb, ctx ) { + var events = this._events; + + if ( !events ) { + return this; + } + + if ( !name && !cb && !ctx ) { + this._events = []; + return this; + } + + eachEvent( name, cb, function( name, cb ) { + $.each( findHandlers( events, name, cb, ctx ), function() { + delete events[ this.id ]; + }); + }); + + return this; + }, + + /** + * 瑙﹀彂浜嬩欢 + * @method trigger + * @grammar trigger( name[, args...] ) => self + * @param {String} type 浜嬩欢鍚� + * @param {*} [...] 浠绘剰鍙傛暟 + * @return {Boolean} 濡傛灉handler涓璻eturn false浜嗭紝鍒欒繑鍥瀎alse, 鍚﹀垯杩斿洖true + */ + trigger: function( type ) { + var args, events, allEvents; + + if ( !this._events || !type ) { + return this; + } + + args = slice.call( arguments, 1 ); + events = findHandlers( this._events, type ); + allEvents = findHandlers( this._events, 'all' ); + + return triggerHanders( events, args ) && + triggerHanders( allEvents, arguments ); + } + }; + + /** + * 涓粙鑰咃紝瀹冩湰韬槸涓崟渚嬶紝浣嗗彲浠ラ�氳繃[installTo](#WebUploader:Mediator:installTo)鏂规硶锛屼娇浠讳綍瀵硅薄鍏峰浜嬩欢琛屼负銆� + * 涓昏鐩殑鏄礋璐fā鍧椾笌妯″潡涔嬮棿鐨勫悎浣滐紝闄嶄綆鑰﹀悎搴︺�� + * + * @class Mediator + */ + return $.extend({ + + /** + * 鍙互閫氳繃杩欎釜鎺ュ彛锛屼娇浠讳綍瀵硅薄鍏峰浜嬩欢鍔熻兘銆� + * @method installTo + * @param {Object} obj 闇�瑕佸叿澶囦簨浠惰涓虹殑瀵硅薄銆� + * @return {Object} 杩斿洖obj. + */ + installTo: function( obj ) { + return $.extend( obj, protos ); + } + + }, protos ); + }); + /** + * @fileOverview Uploader涓婁紶绫� + */ + define('uploader',[ + 'base', + 'mediator' + ], function( Base, Mediator ) { + + var $ = Base.$; + + /** + * 涓婁紶鍏ュ彛绫汇�� + * @class Uploader + * @constructor + * @grammar new Uploader( opts ) => Uploader + * @example + * var uploader = WebUploader.Uploader({ + * swf: 'path_of_swf/Uploader.swf', + * + * // 寮�璧峰垎鐗囦笂浼犮�� + * chunked: true + * }); + */ + function Uploader( opts ) { + this.options = $.extend( true, {}, Uploader.options, opts ); + this._init( this.options ); + } + + // default Options + // widgets涓湁鐩稿簲鎵╁睍 + Uploader.options = {}; + Mediator.installTo( Uploader.prototype ); + + // 鎵归噺娣诲姞绾懡浠ゅ紡鏂规硶銆� + $.each({ + upload: 'start-upload', + stop: 'stop-upload', + getFile: 'get-file', + getFiles: 'get-files', + addFile: 'add-file', + addFiles: 'add-file', + sort: 'sort-files', + removeFile: 'remove-file', + skipFile: 'skip-file', + retry: 'retry', + isInProgress: 'is-in-progress', + makeThumb: 'make-thumb', + getDimension: 'get-dimension', + addButton: 'add-btn', + getRuntimeType: 'get-runtime-type', + refresh: 'refresh', + disable: 'disable', + enable: 'enable', + reset: 'reset' + }, function( fn, command ) { + Uploader.prototype[ fn ] = function() { + return this.request( command, arguments ); + }; + }); + + $.extend( Uploader.prototype, { + state: 'pending', + + _init: function( opts ) { + var me = this; + + me.request( 'init', opts, function() { + me.state = 'ready'; + me.trigger('ready'); + }); + }, + + /** + * 鑾峰彇鎴栬�呰缃甎ploader閰嶇疆椤广�� + * @method option + * @grammar option( key ) => * + * @grammar option( key, val ) => self + * @example + * + * // 鍒濆鐘舵�佸浘鐗囦笂浼犲墠涓嶄細鍘嬬缉 + * var uploader = new WebUploader.Uploader({ + * resize: null; + * }); + * + * // 淇敼鍚庡浘鐗囦笂浼犲墠锛屽皾璇曞皢鍥剧墖鍘嬬缉鍒�1600 * 1600 + * uploader.options( 'resize', { + * width: 1600, + * height: 1600 + * }); + */ + option: function( key, val ) { + var opts = this.options; + + // setter + if ( arguments.length > 1 ) { + + if ( $.isPlainObject( val ) && + $.isPlainObject( opts[ key ] ) ) { + $.extend( opts[ key ], val ); + } else { + opts[ key ] = val; + } + + } else { // getter + return key ? opts[ key ] : opts; + } + }, + + /** + * 鑾峰彇鏂囦欢缁熻淇℃伅銆傝繑鍥炰竴涓寘鍚竴涓嬩俊鎭殑瀵硅薄銆� + * * `successNum` 涓婁紶鎴愬姛鐨勬枃浠舵暟 + * * `uploadFailNum` 涓婁紶澶辫触鐨勬枃浠舵暟 + * * `cancelNum` 琚垹闄ょ殑鏂囦欢鏁� + * * `invalidNum` 鏃犳晥鐨勬枃浠舵暟 + * * `queueNum` 杩樺湪闃熷垪涓殑鏂囦欢鏁� + * @method getStats + * @grammar getStats() => Object + */ + getStats: function() { + // return this._mgr.getStats.apply( this._mgr, arguments ); + var stats = this.request('get-stats'); + + return { + successNum: stats.numOfSuccess, + + // who care? + // queueFailNum: 0, + cancelNum: stats.numOfCancel, + invalidNum: stats.numOfInvalid, + uploadFailNum: stats.numOfUploadFailed, + queueNum: stats.numOfQueue + }; + }, + + // 闇�瑕侀噸鍐欐鏂规硶鏉ユ潵鏀寔opts.onEvent鍜宨nstance.onEvent鐨勫鐞嗗櫒 + trigger: function( type/*, args...*/ ) { + var args = [].slice.call( arguments, 1 ), + opts = this.options, + name = 'on' + type.substring( 0, 1 ).toUpperCase() + + type.substring( 1 ); + + if ( + // 璋冪敤閫氳繃on鏂规硶娉ㄥ唽鐨刪andler. + Mediator.trigger.apply( this, arguments ) === false || + + // 璋冪敤opts.onEvent + $.isFunction( opts[ name ] ) && + opts[ name ].apply( this, args ) === false || + + // 璋冪敤this.onEvent + $.isFunction( this[ name ] ) && + this[ name ].apply( this, args ) === false || + + // 骞挎挱鎵�鏈塽ploader鐨勪簨浠躲�� + Mediator.trigger.apply( Mediator, + [ this, type ].concat( args ) ) === false ) { + + return false; + } + + return true; + }, + + // widgets/widget.js灏嗚ˉ鍏呮鏂规硶鐨勮缁嗘枃妗c�� + request: Base.noop + }); + + /** + * 鍒涘缓Uploader瀹炰緥锛岀瓑鍚屼簬new Uploader( opts ); + * @method create + * @class Base + * @static + * @grammar Base.create( opts ) => Uploader + */ + Base.create = Uploader.create = function( opts ) { + return new Uploader( opts ); + }; + + // 鏆撮湶Uploader锛屽彲浠ラ�氳繃瀹冩潵鎵╁睍涓氬姟閫昏緫銆� + Base.Uploader = Uploader; + + return Uploader; + }); + /** + * @fileOverview Runtime绠$悊鍣紝璐熻矗Runtime鐨勯�夋嫨, 杩炴帴 + */ + define('runtime/runtime',[ + 'base', + 'mediator' + ], function( Base, Mediator ) { + + var $ = Base.$, + factories = {}, + + // 鑾峰彇瀵硅薄鐨勭涓�涓猭ey + getFirstKey = function( obj ) { + for ( var key in obj ) { + if ( obj.hasOwnProperty( key ) ) { + return key; + } + } + return null; + }; + + // 鎺ュ彛绫汇�� + function Runtime( options ) { + this.options = $.extend({ + container: document.body + }, options ); + this.uid = Base.guid('rt_'); + } + + $.extend( Runtime.prototype, { + + getContainer: function() { + var opts = this.options, + parent, container; + + if ( this._container ) { + return this._container; + } + + parent = $( opts.container || document.body ); + container = $( document.createElement('div') ); + + container.attr( 'id', 'rt_' + this.uid ); + container.css({ + position: 'absolute', + top: '0px', + left: '0px', + width: '1px', + height: '1px', + overflow: 'hidden' + }); + + parent.append( container ); + parent.addClass('webuploader-container'); + this._container = container; + return container; + }, + + init: Base.noop, + exec: Base.noop, + + destroy: function() { + if ( this._container ) { + this._container.parentNode.removeChild( this.__container ); + } + + this.off(); + } + }); + + Runtime.orders = 'html5,flash'; + + + /** + * 娣诲姞Runtime瀹炵幇銆� + * @param {String} type 绫诲瀷 + * @param {Runtime} factory 鍏蜂綋Runtime瀹炵幇銆� + */ + Runtime.addRuntime = function( type, factory ) { + factories[ type ] = factory; + }; + + Runtime.hasRuntime = function( type ) { + return !!(type ? factories[ type ] : getFirstKey( factories )); + }; + + Runtime.create = function( opts, orders ) { + var type, runtime; + + orders = orders || Runtime.orders; + $.each( orders.split( /\s*,\s*/g ), function() { + if ( factories[ this ] ) { + type = this; + return false; + } + }); + + type = type || getFirstKey( factories ); + + if ( !type ) { + throw new Error('Runtime Error'); + } + + runtime = new factories[ type ]( opts ); + return runtime; + }; + + Mediator.installTo( Runtime.prototype ); + return Runtime; + }); + + /** + * @fileOverview Runtime绠$悊鍣紝璐熻矗Runtime鐨勯�夋嫨, 杩炴帴 + */ + define('runtime/client',[ + 'base', + 'mediator', + 'runtime/runtime' + ], function( Base, Mediator, Runtime ) { + + var cache; + + cache = (function() { + var obj = {}; + + return { + add: function( runtime ) { + obj[ runtime.uid ] = runtime; + }, + + get: function( ruid, standalone ) { + var i; + + if ( ruid ) { + return obj[ ruid ]; + } + + for ( i in obj ) { + // 鏈変簺绫诲瀷涓嶈兘閲嶇敤锛屾瘮濡俧ilepicker. + if ( standalone && obj[ i ].__standalone ) { + continue; + } + + return obj[ i ]; + } + + return null; + }, + + remove: function( runtime ) { + delete obj[ runtime.uid ]; + } + }; + })(); + + function RuntimeClient( component, standalone ) { + var deferred = Base.Deferred(), + runtime; + + this.uid = Base.guid('client_'); + + // 鍏佽runtime娌℃湁鍒濆鍖栦箣鍓嶏紝娉ㄥ唽涓�浜涙柟娉曞湪鍒濆鍖栧悗鎵ц銆� + this.runtimeReady = function( cb ) { + return deferred.done( cb ); + }; + + this.connectRuntime = function( opts, cb ) { + + // already connected. + if ( runtime ) { + throw new Error('already connected!'); + } + + deferred.done( cb ); + + if ( typeof opts === 'string' && cache.get( opts ) ) { + runtime = cache.get( opts ); + } + + // 鍍廸ilePicker鍙兘鐙珛瀛樺湪锛屼笉鑳藉叕鐢ㄣ�� + runtime = runtime || cache.get( null, standalone ); + + // 闇�瑕佸垱寤� + if ( !runtime ) { + runtime = Runtime.create( opts, opts.runtimeOrder ); + runtime.__promise = deferred.promise(); + runtime.once( 'ready', deferred.resolve ); + runtime.init(); + cache.add( runtime ); + runtime.__client = 1; + } else { + // 鏉ヨ嚜cache + Base.$.extend( runtime.options, opts ); + runtime.__promise.then( deferred.resolve ); + runtime.__client++; + } + + standalone && (runtime.__standalone = standalone); + return runtime; + }; + + this.getRuntime = function() { + return runtime; + }; + + this.disconnectRuntime = function() { + if ( !runtime ) { + return; + } + + runtime.__client--; + + if ( runtime.__client <= 0 ) { + cache.remove( runtime ); + delete runtime.__promise; + runtime.destroy(); + } + + runtime = null; + }; + + this.exec = function() { + if ( !runtime ) { + return; + } + + var args = Base.slice( arguments ); + component && args.unshift( component ); + + return runtime.exec.apply( this, args ); + }; + + this.getRuid = function() { + return runtime && runtime.uid; + }; + + this.destroy = (function( destroy ) { + return function() { + destroy && destroy.apply( this, arguments ); + this.trigger('destroy'); + this.off(); + this.exec('destroy'); + this.disconnectRuntime(); + }; + })( this.destroy ); + } + + Mediator.installTo( RuntimeClient.prototype ); + return RuntimeClient; + }); + /** + * @fileOverview 閿欒淇℃伅 + */ + define('lib/dnd',[ + 'base', + 'mediator', + 'runtime/client' + ], function( Base, Mediator, RuntimeClent ) { + + var $ = Base.$; + + function DragAndDrop( opts ) { + opts = this.options = $.extend({}, DragAndDrop.options, opts ); + + opts.container = $( opts.container ); + + if ( !opts.container.length ) { + return; + } + + RuntimeClent.call( this, 'DragAndDrop' ); + } + + DragAndDrop.options = { + accept: null, + disableGlobalDnd: false + }; + + Base.inherits( RuntimeClent, { + constructor: DragAndDrop, + + init: function() { + var me = this; + + me.connectRuntime( me.options, function() { + me.exec('init'); + me.trigger('ready'); + }); + }, + + destroy: function() { + this.disconnectRuntime(); + } + }); + + Mediator.installTo( DragAndDrop.prototype ); + + return DragAndDrop; + }); + /** + * @fileOverview 缁勪欢鍩虹被銆� + */ + define('widgets/widget',[ + 'base', + 'uploader' + ], function( Base, Uploader ) { + + var $ = Base.$, + _init = Uploader.prototype._init, + IGNORE = {}, + widgetClass = []; + + function isArrayLike( obj ) { + if ( !obj ) { + return false; + } + + var length = obj.length, + type = $.type( obj ); + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === 'array' || type !== 'function' && type !== 'string' && + (length === 0 || typeof length === 'number' && length > 0 && + (length - 1) in obj); + } + + function Widget( uploader ) { + this.owner = uploader; + this.options = uploader.options; + } + + $.extend( Widget.prototype, { + + init: Base.noop, + + // 绫籅ackbone鐨勪簨浠剁洃鍚0鏄庯紝鐩戝惉uploader瀹炰緥涓婄殑浜嬩欢 + // widget鐩存帴鏃犳硶鐩戝惉浜嬩欢锛屼簨浠跺彧鑳介�氳繃uploader鏉ヤ紶閫� + invoke: function( apiName, args ) { + + /* + { + 'make-thumb': 'makeThumb' + } + */ + var map = this.responseMap; + + // 濡傛灉鏃燗PI鍝嶅簲澹版槑鍒欏拷鐣� + if ( !map || !(apiName in map) || !(map[ apiName ] in this) || + !$.isFunction( this[ map[ apiName ] ] ) ) { + + return IGNORE; + } + + return this[ map[ apiName ] ].apply( this, args ); + + }, + + /** + * 鍙戦�佸懡浠ゃ�傚綋浼犲叆`callback`鎴栬�卄handler`涓繑鍥瀈promise`鏃躲�傝繑鍥炰竴涓綋鎵�鏈塦handler`涓殑promise閮藉畬鎴愬悗瀹屾垚鐨勬柊`promise`銆� + * @method request + * @grammar request( command, args ) => * | Promise + * @grammar request( command, args, callback ) => Promise + * @for Uploader + */ + request: function() { + return this.owner.request.apply( this.owner, arguments ); + } + }); + + // 鎵╁睍Uploader. + $.extend( Uploader.prototype, { + + // 瑕嗗啓_init鐢ㄦ潵鍒濆鍖杦idgets + _init: function() { + var me = this, + widgets = me._widgets = []; + + $.each( widgetClass, function( _, klass ) { + widgets.push( new klass( me ) ); + }); + + return _init.apply( me, arguments ); + }, + + request: function( apiName, args, callback ) { + var i = 0, + widgets = this._widgets, + len = widgets.length, + rlts = [], + dfds = [], + widget, rlt, promise, key; + + args = isArrayLike( args ) ? args : [ args ]; + + for ( ; i < len; i++ ) { + widget = widgets[ i ]; + rlt = widget.invoke( apiName, args ); + + if ( rlt !== IGNORE ) { + + // Deferred瀵硅薄 + if ( Base.isPromise( rlt ) ) { + dfds.push( rlt ); + } else { + rlts.push( rlt ); + } + } + } + + // 濡傛灉鏈塩allback锛屽垯鐢ㄥ紓姝ユ柟寮忋�� + if ( callback || dfds.length ) { + promise = Base.when.apply( Base, dfds ); + key = promise.pipe ? 'pipe' : 'then'; + + // 寰堥噸瑕佷笉鑳藉垹闄ゃ�傚垹闄や簡浼氭寰幆銆� + // 淇濊瘉鎵ц椤哄簭銆傝callback鎬绘槸鍦ㄤ笅涓�涓猼ick涓墽琛屻�� + return promise[ key ](function() { + var deferred = Base.Deferred(), + args = arguments; + + setTimeout(function() { + deferred.resolve.apply( deferred, args ); + }, 1 ); + + return deferred.promise(); + })[ key ]( callback || Base.noop ); + } else { + return rlts[ 0 ]; + } + } + }); + + /** + * 娣诲姞缁勪欢 + * @param {object} widgetProto 缁勪欢鍘熷瀷锛屾瀯閫犲嚱鏁伴�氳繃constructor灞炴�у畾涔� + * @param {object} responseMap API鍚嶇О涓庡嚱鏁板疄鐜扮殑鏄犲皠 + * @example + * Uploader.register( { + * init: function( options ) {}, + * makeThumb: function() {} + * }, { + * 'make-thumb': 'makeThumb' + * } ); + */ + Uploader.register = Widget.register = function( responseMap, widgetProto ) { + var map = { init: 'init' }, + klass; + + if ( arguments.length === 1 ) { + widgetProto = responseMap; + widgetProto.responseMap = map; + } else { + widgetProto.responseMap = $.extend( map, responseMap ); + } + + klass = Base.inherits( Widget, widgetProto ); + widgetClass.push( klass ); + + return klass; + }; + + return Widget; + }); + /** + * @fileOverview DragAndDrop Widget銆� + */ + define('widgets/filednd',[ + 'base', + 'uploader', + 'lib/dnd', + 'widgets/widget' + ], function( Base, Uploader, Dnd ) { + var $ = Base.$; + + Uploader.options.dnd = ''; + + /** + * @property {Selector} [dnd=undefined] 鎸囧畾Drag And Drop鎷栨嫿鐨勫鍣紝濡傛灉涓嶆寚瀹氾紝鍒欎笉鍚姩銆� + * @namespace options + * @for Uploader + */ + + /** + * @event dndAccept + * @param {DataTransferItemList} items DataTransferItem + * @description 闃绘姝や簨浠跺彲浠ユ嫆缁濇煇浜涚被鍨嬬殑鏂囦欢鎷栧叆杩涙潵銆傜洰鍓嶅彧鏈� chrome 鎻愪緵杩欐牱鐨� API锛屼笖鍙兘閫氳繃 mime-type 楠岃瘉銆� + * @for Uploader + */ + return Uploader.register({ + init: function( opts ) { + + if ( !opts.dnd || + this.request('predict-runtime-type') !== 'html5' ) { + return; + } + + var me = this, + deferred = Base.Deferred(), + options = $.extend({}, { + disableGlobalDnd: opts.disableGlobalDnd, + container: opts.dnd, + accept: opts.accept + }), + dnd; + + dnd = new Dnd( options ); + + dnd.once( 'ready', deferred.resolve ); + dnd.on( 'drop', function( files ) { + me.request( 'add-file', [ files ]); + }); + + // 妫�娴嬫枃浠舵槸鍚﹀叏閮ㄥ厑璁告坊鍔犮�� + dnd.on( 'accept', function( items ) { + return me.owner.trigger( 'dndAccept', items ); + }); + + dnd.init(); + + return deferred.promise(); + } + }); + }); + + /** + * @fileOverview 閿欒淇℃伅 + */ + define('lib/filepaste',[ + 'base', + 'mediator', + 'runtime/client' + ], function( Base, Mediator, RuntimeClent ) { + + var $ = Base.$; + + function FilePaste( opts ) { + opts = this.options = $.extend({}, opts ); + opts.container = $( opts.container || document.body ); + RuntimeClent.call( this, 'FilePaste' ); + } + + Base.inherits( RuntimeClent, { + constructor: FilePaste, + + init: function() { + var me = this; + + me.connectRuntime( me.options, function() { + me.exec('init'); + me.trigger('ready'); + }); + }, + + destroy: function() { + this.exec('destroy'); + this.disconnectRuntime(); + this.off(); + } + }); + + Mediator.installTo( FilePaste.prototype ); + + return FilePaste; + }); + /** + * @fileOverview 缁勪欢鍩虹被銆� + */ + define('widgets/filepaste',[ + 'base', + 'uploader', + 'lib/filepaste', + 'widgets/widget' + ], function( Base, Uploader, FilePaste ) { + var $ = Base.$; + + /** + * @property {Selector} [paste=undefined] 鎸囧畾鐩戝惉paste浜嬩欢鐨勫鍣紝濡傛灉涓嶆寚瀹氾紝涓嶅惎鐢ㄦ鍔熻兘銆傛鍔熻兘涓洪�氳繃绮樿创鏉ユ坊鍔犳埅灞忕殑鍥剧墖銆傚缓璁缃负`document.body`. + * @namespace options + * @for Uploader + */ + return Uploader.register({ + init: function( opts ) { + + if ( !opts.paste || + this.request('predict-runtime-type') !== 'html5' ) { + return; + } + + var me = this, + deferred = Base.Deferred(), + options = $.extend({}, { + container: opts.paste, + accept: opts.accept + }), + paste; + + paste = new FilePaste( options ); + + paste.once( 'ready', deferred.resolve ); + paste.on( 'paste', function( files ) { + me.owner.request( 'add-file', [ files ]); + }); + paste.init(); + + return deferred.promise(); + } + }); + }); + /** + * @fileOverview Blob + */ + define('lib/blob',[ + 'base', + 'runtime/client' + ], function( Base, RuntimeClient ) { + + function Blob( ruid, source ) { + var me = this; + + me.source = source; + me.ruid = ruid; + + RuntimeClient.call( me, 'Blob' ); + + this.uid = source.uid || this.uid; + this.type = source.type || ''; + this.size = source.size || 0; + + if ( ruid ) { + me.connectRuntime( ruid ); + } + } + + Base.inherits( RuntimeClient, { + constructor: Blob, + + slice: function( start, end ) { + return this.exec( 'slice', start, end ); + }, + + getSource: function() { + return this.source; + } + }); + + return Blob; + }); + /** + * 涓轰簡缁熶竴鍖朏lash鐨凢ile鍜孒TML5鐨凢ile鑰屽瓨鍦ㄣ�� + * 浠ヨ嚦浜庤璋冪敤Flash閲岄潰鐨凢ile锛屼篃鍙互鍍忚皟鐢℉TML5鐗堟湰鐨凢ile涓�涓嬨�� + * @fileOverview File + */ + define('lib/file',[ + 'base', + 'lib/blob' + ], function( Base, Blob ) { + + var uid = 1, + rExt = /\.([^.]+)$/; + + function File( ruid, file ) { + var ext; + + Blob.apply( this, arguments ); + this.name = file.name || ('untitled' + uid++); + ext = rExt.exec( file.name ) ? RegExp.$1.toLowerCase() : ''; + + // todo 鏀寔鍏朵粬绫诲瀷鏂囦欢鐨勮浆鎹€�� + + // 濡傛灉鏈塵imetype, 浣嗘槸鏂囦欢鍚嶉噷闈㈡病鏈夋壘鍑哄悗缂�瑙勫緥 + if ( !ext && this.type ) { + ext = /\/(jpg|jpeg|png|gif|bmp)$/i.exec( this.type ) ? + RegExp.$1.toLowerCase() : ''; + this.name += '.' + ext; + } + + // 濡傛灉娌℃湁鎸囧畾mimetype, 浣嗘槸鐭ラ亾鏂囦欢鍚庣紑銆� + if ( !this.type && ~'jpg,jpeg,png,gif,bmp'.indexOf( ext ) ) { + this.type = 'image/' + (ext === 'jpg' ? 'jpeg' : ext); + } + + this.ext = ext; + this.lastModifiedDate = file.lastModifiedDate || + (new Date()).toLocaleString(); + } + + return Base.inherits( Blob, File ); + }); + + /** + * @fileOverview 閿欒淇℃伅 + */ + define('lib/filepicker',[ + 'base', + 'runtime/client', + 'lib/file' + ], function( Base, RuntimeClent, File ) { + + var $ = Base.$; + + function FilePicker( opts ) { + opts = this.options = $.extend({}, FilePicker.options, opts ); + + opts.container = $( opts.id ); + + if ( !opts.container.length ) { + throw new Error('鎸夐挳鎸囧畾閿欒'); + } + + opts.innerHTML = opts.innerHTML || opts.label || + opts.container.html() || ''; + + opts.button = $( opts.button || document.createElement('div') ); + opts.button.html( opts.innerHTML ); + opts.container.html( opts.button ); + + RuntimeClent.call( this, 'FilePicker', true ); + } + + FilePicker.options = { + button: null, + container: null, + label: null, + innerHTML: null, + multiple: true, + accept: null, + name: 'file' + }; + + Base.inherits( RuntimeClent, { + constructor: FilePicker, + + init: function() { + var me = this, + opts = me.options, + button = opts.button; + + button.addClass('webuploader-pick'); + + me.on( 'all', function( type ) { + var files; + + switch ( type ) { + case 'mouseenter': + button.addClass('webuploader-pick-hover'); + break; + + case 'mouseleave': + button.removeClass('webuploader-pick-hover'); + break; + + case 'change': + files = me.exec('getFiles'); + me.trigger( 'select', $.map( files, function( file ) { + file = new File( me.getRuid(), file ); + + // 璁板綍鏉ユ簮銆� + file._refer = opts.container; + return file; + }), opts.container ); + break; + } + }); + + me.connectRuntime( opts, function() { + me.refresh(); + me.exec( 'init', opts ); + me.trigger('ready'); + }); + + $( window ).on( 'resize', function() { + me.refresh(); + }); + }, + + refresh: function() { + var shimContainer = this.getRuntime().getContainer(), + button = this.options.button, + width = button.outerWidth ? + button.outerWidth() : button.width(), + + height = button.outerHeight ? + button.outerHeight() : button.height(), + + pos = button.offset(); + + width && height && shimContainer.css({ + bottom: 'auto', + right: 'auto', + width: width + 'px', + height: height + 'px' + }).offset( pos ); + }, + + enable: function() { + var btn = this.options.button; + + btn.removeClass('webuploader-pick-disable'); + this.refresh(); + }, + + disable: function() { + var btn = this.options.button; + + this.getRuntime().getContainer().css({ + top: '-99999px' + }); + + btn.addClass('webuploader-pick-disable'); + }, + + destroy: function() { + if ( this.runtime ) { + this.exec('destroy'); + this.disconnectRuntime(); + } + } + }); + + return FilePicker; + }); + + /** + * @fileOverview 鏂囦欢閫夋嫨鐩稿叧 + */ + define('widgets/filepicker',[ + 'base', + 'uploader', + 'lib/filepicker', + 'widgets/widget' + ], function( Base, Uploader, FilePicker ) { + var $ = Base.$; + + $.extend( Uploader.options, { + + /** + * @property {Selector | Object} [pick=undefined] + * @namespace options + * @for Uploader + * @description 鎸囧畾閫夋嫨鏂囦欢鐨勬寜閽鍣紝涓嶆寚瀹氬垯涓嶅垱寤烘寜閽�� + * + * * `id` {Seletor} 鎸囧畾閫夋嫨鏂囦欢鐨勬寜閽鍣紝涓嶆寚瀹氬垯涓嶅垱寤烘寜閽�� + * * `label` {String} 璇烽噰鐢� `innerHTML` 浠f浛 + * * `innerHTML` {String} 鎸囧畾鎸夐挳鏂囧瓧銆備笉鎸囧畾鏃朵紭鍏堜粠鎸囧畾鐨勫鍣ㄤ腑鐪嬫槸鍚﹁嚜甯︽枃瀛椼�� + * * `multiple` {Boolean} 鏄惁寮�璧峰悓鏃堕�夋嫨澶氫釜鏂囦欢鑳藉姏銆� + */ + pick: null, + + /** + * @property {Arroy} [accept=null] + * @namespace options + * @for Uploader + * @description 鎸囧畾鎺ュ彈鍝簺绫诲瀷鐨勬枃浠躲�� 鐢变簬鐩墠杩樻湁ext杞琺imeType琛紝鎵�浠ヨ繖閲岄渶瑕佸垎寮�鎸囧畾銆� + * + * * `title` {String} 鏂囧瓧鎻忚堪 + * * `extensions` {String} 鍏佽鐨勬枃浠跺悗缂�锛屼笉甯︾偣锛屽涓敤閫楀彿鍒嗗壊銆� + * * `mimeTypes` {String} 澶氫釜鐢ㄩ�楀彿鍒嗗壊銆� + * + * 濡傦細 + * + * ``` + * { + * title: 'Images', + * extensions: 'gif,jpg,jpeg,bmp,png', + * mimeTypes: 'image/*' + * } + * ``` + */ + accept: null/*{ + title: 'Images', + extensions: 'gif,jpg,jpeg,bmp,png', + mimeTypes: 'image/*' + }*/ + }); + + return Uploader.register({ + 'add-btn': 'addButton', + refresh: 'refresh', + disable: 'disable', + enable: 'enable' + }, { + + init: function( opts ) { + this.pickers = []; + return opts.pick && this.addButton( opts.pick ); + }, + + refresh: function() { + $.each( this.pickers, function() { + this.refresh(); + }); + }, + + /** + * @method addButton + * @for Uploader + * @grammar addButton( pick ) => Promise + * @description + * 娣诲姞鏂囦欢閫夋嫨鎸夐挳锛屽鏋滀竴涓寜閽笉澶燂紝闇�瑕佽皟鐢ㄦ鏂规硶鏉ユ坊鍔犮�傚弬鏁拌窡[options.pick](#WebUploader:Uploader:options)涓�鑷淬�� + * @example + * uploader.addButton({ + * id: '#btnContainer', + * innerHTML: '閫夋嫨鏂囦欢' + * }); + */ + addButton: function( pick ) { + var me = this, + opts = me.options, + accept = opts.accept, + options, picker, deferred; + + if ( !pick ) { + return; + } + + deferred = Base.Deferred(); + $.isPlainObject( pick ) || (pick = { + id: pick + }); + + options = $.extend({}, pick, { + accept: $.isPlainObject( accept ) ? [ accept ] : accept, + swf: opts.swf, + runtimeOrder: opts.runtimeOrder + }); + + picker = new FilePicker( options ); + + picker.once( 'ready', deferred.resolve ); + picker.on( 'select', function( files ) { + me.owner.request( 'add-file', [ files ]); + }); + picker.init(); + + this.pickers.push( picker ); + + return deferred.promise(); + }, + + disable: function() { + $.each( this.pickers, function() { + this.disable(); + }); + }, + + enable: function() { + $.each( this.pickers, function() { + this.enable(); + }); + } + }); + }); + /** + * @fileOverview Image + */ + define('lib/image',[ + 'base', + 'runtime/client', + 'lib/blob' + ], function( Base, RuntimeClient, Blob ) { + var $ = Base.$; + + // 鏋勯�犲櫒銆� + function Image( opts ) { + this.options = $.extend({}, Image.options, opts ); + RuntimeClient.call( this, 'Image' ); + + this.on( 'load', function() { + this._info = this.exec('info'); + this._meta = this.exec('meta'); + }); + } + + // 榛樿閫夐」銆� + Image.options = { + + // 榛樿鐨勫浘鐗囧鐞嗚川閲� + quality: 90, + + // 鏄惁瑁佸壀 + crop: false, + + // 鏄惁淇濈暀澶撮儴淇℃伅 + preserveHeaders: true, + + // 鏄惁鍏佽鏀惧ぇ銆� + allowMagnify: true + }; + + // 缁ф壙RuntimeClient. + Base.inherits( RuntimeClient, { + constructor: Image, + + info: function( val ) { + + // setter + if ( val ) { + this._info = val; + return this; + } + + // getter + return this._info; + }, + + meta: function( val ) { + + // setter + if ( val ) { + this._meta = val; + return this; + } + + // getter + return this._meta; + }, + + loadFromBlob: function( blob ) { + var me = this, + ruid = blob.getRuid(); + + this.connectRuntime( ruid, function() { + me.exec( 'init', me.options ); + me.exec( 'loadFromBlob', blob ); + }); + }, + + resize: function() { + var args = Base.slice( arguments ); + return this.exec.apply( this, [ 'resize' ].concat( args ) ); + }, + + getAsDataUrl: function( type ) { + return this.exec( 'getAsDataUrl', type ); + }, + + getAsBlob: function( type ) { + var blob = this.exec( 'getAsBlob', type ); + + return new Blob( this.getRuid(), blob ); + } + }); + + return Image; + }); + /** + * @fileOverview 鍥剧墖鎿嶄綔, 璐熻矗棰勮鍥剧墖鍜屼笂浼犲墠鍘嬬缉鍥剧墖 + */ + define('widgets/image',[ + 'base', + 'uploader', + 'lib/image', + 'widgets/widget' + ], function( Base, Uploader, Image ) { + + var $ = Base.$, + throttle; + + // 鏍规嵁瑕佸鐞嗙殑鏂囦欢澶у皬鏉ヨ妭娴侊紝涓�娆′笉鑳藉鐞嗗お澶氾紝浼氬崱銆� + throttle = (function( max ) { + var occupied = 0, + waiting = [], + tick = function() { + var item; + + while ( waiting.length && occupied < max ) { + item = waiting.shift(); + occupied += item[ 0 ]; + item[ 1 ](); + } + }; + + return function( emiter, size, cb ) { + waiting.push([ size, cb ]); + emiter.once( 'destroy', function() { + occupied -= size; + setTimeout( tick, 1 ); + }); + setTimeout( tick, 1 ); + }; + })( 5 * 1024 * 1024 ); + + $.extend( Uploader.options, { + + /** + * @property {Object} [thumb] + * @namespace options + * @for Uploader + * @description 閰嶇疆鐢熸垚缂╃暐鍥剧殑閫夐」銆� + * + * 榛樿涓猴細 + * + * ```javascript + * { + * width: 110, + * height: 110, + * + * // 鍥剧墖璐ㄩ噺锛屽彧鏈塼ype涓篳image/jpeg`鐨勬椂鍊欐墠鏈夋晥銆� + * quality: 70, + * + * // 鏄惁鍏佽鏀惧ぇ锛屽鏋滄兂瑕佺敓鎴愬皬鍥剧殑鏃跺�欎笉澶辩湡锛屾閫夐」搴旇璁剧疆涓篺alse. + * allowMagnify: true, + * + * // 鏄惁鍏佽瑁佸壀銆� + * crop: true, + * + * // 鏄惁淇濈暀澶撮儴meta淇℃伅銆� + * preserveHeaders: false, + * + * // 涓虹┖鐨勮瘽鍒欎繚鐣欏師鏈夊浘鐗囨牸寮忋�� + * // 鍚﹀垯寮哄埗杞崲鎴愭寚瀹氱殑绫诲瀷銆� + * type: 'image/jpeg' + * } + * ``` + */ + thumb: { + width: 110, + height: 110, + quality: 70, + allowMagnify: true, + crop: true, + preserveHeaders: false, + + // 涓虹┖鐨勮瘽鍒欎繚鐣欏師鏈夊浘鐗囨牸寮忋�� + // 鍚﹀垯寮哄埗杞崲鎴愭寚瀹氱殑绫诲瀷銆� + // IE 8涓嬮潰 base64 澶у皬涓嶈兘瓒呰繃 32K 鍚﹀垯棰勮澶辫触锛岃�岄潪 jpeg 缂栫爜鐨勫浘鐗囧緢鍙� + // 鑳戒細瓒呰繃 32k, 鎵�浠ヨ繖閲岃缃垚棰勮鐨勬椂鍊欓兘鏄� image/jpeg + type: 'image/jpeg' + }, + + /** + * @property {Object} [compress] + * @namespace options + * @for Uploader + * @description 閰嶇疆鍘嬬缉鐨勫浘鐗囩殑閫夐」銆傚鏋滄閫夐」涓篳false`, 鍒欏浘鐗囧湪涓婁紶鍓嶄笉杩涜鍘嬬缉銆� + * + * 榛樿涓猴細 + * + * ```javascript + * { + * width: 1600, + * height: 1600, + * + * // 鍥剧墖璐ㄩ噺锛屽彧鏈塼ype涓篳image/jpeg`鐨勬椂鍊欐墠鏈夋晥銆� + * quality: 90, + * + * // 鏄惁鍏佽鏀惧ぇ锛屽鏋滄兂瑕佺敓鎴愬皬鍥剧殑鏃跺�欎笉澶辩湡锛屾閫夐」搴旇璁剧疆涓篺alse. + * allowMagnify: false, + * + * // 鏄惁鍏佽瑁佸壀銆� + * crop: false, + * + * // 鏄惁淇濈暀澶撮儴meta淇℃伅銆� + * preserveHeaders: true + * } + * ``` + */ + compress: { + width: 1600, + height: 1600, + quality: 90, + allowMagnify: false, + crop: false, + preserveHeaders: true + } + }); + + return Uploader.register({ + 'make-thumb': 'makeThumb', + 'before-send-file': 'compressImage' + }, { + + + /** + * 鐢熸垚缂╃暐鍥撅紝姝よ繃绋嬩负寮傛锛屾墍浠ラ渶瑕佷紶鍏callback`銆� + * 閫氬父鎯呭喌鍦ㄥ浘鐗囧姞鍏ラ槦閲屽悗璋冪敤姝ゆ柟娉曟潵鐢熸垚棰勮鍥句互澧炲己浜や簰鏁堟灉銆� + * + * `callback`涓彲浠ユ帴鏀跺埌涓や釜鍙傛暟銆� + * * 绗竴涓负error锛屽鏋滅敓鎴愮缉鐣ュ浘鏈夐敊璇紝姝rror灏嗕负鐪熴�� + * * 绗簩涓负ret, 缂╃暐鍥剧殑Data URL鍊笺�� + * + * **娉ㄦ剰** + * Date URL鍦↖E6/7涓笉鏀寔锛屾墍浠ヤ笉鐢ㄨ皟鐢ㄦ鏂规硶浜嗭紝鐩存帴鏄剧ず涓�寮犳殏涓嶆敮鎸侀瑙堝浘鐗囧ソ浜嗐�� + * + * + * @method makeThumb + * @grammar makeThumb( file, callback ) => undefined + * @grammar makeThumb( file, callback, width, height ) => undefined + * @for Uploader + * @example + * + * uploader.on( 'fileQueued', function( file ) { + * var $li = ...; + * + * uploader.makeThumb( file, function( error, ret ) { + * if ( error ) { + * $li.text('棰勮閿欒'); + * } else { + * $li.append('<img alt="" src="' + ret + '" />'); + * } + * }); + * + * }); + */ + makeThumb: function( file, cb, width, height ) { + var opts, image; + + file = this.request( 'get-file', file ); + + // 鍙瑙堝浘鐗囨牸寮忋�� + if ( !file.type.match( /^image/ ) ) { + cb( true ); + return; + } + + opts = $.extend({}, this.options.thumb ); + + // 濡傛灉浼犲叆鐨勬槸object. + if ( $.isPlainObject( width ) ) { + opts = $.extend( opts, width ); + width = null; + } + + width = width || opts.width; + height = height || opts.height; + + image = new Image( opts ); + + image.once( 'load', function() { + file._info = file._info || image.info(); + file._meta = file._meta || image.meta(); + image.resize( width, height ); + }); + + image.once( 'complete', function() { + cb( false, image.getAsDataUrl( opts.type ) ); + image.destroy(); + }); + + image.once( 'error', function() { + cb( true ); + image.destroy(); + }); + + throttle( image, file.source.size, function() { + file._info && image.info( file._info ); + file._meta && image.meta( file._meta ); + image.loadFromBlob( file.source ); + }); + }, + + compressImage: function( file ) { + var opts = this.options.compress || this.options.resize, + compressSize = opts && opts.compressSize || 300 * 1024, + image, deferred; + + file = this.request( 'get-file', file ); + + // 鍙瑙堝浘鐗囨牸寮忋�� + if ( !opts || !~'image/jpeg,image/jpg'.indexOf( file.type ) || + file.size < compressSize || + file._compressed ) { + return; + } + + opts = $.extend({}, opts ); + deferred = Base.Deferred(); + + image = new Image( opts ); + + deferred.always(function() { + image.destroy(); + image = null; + }); + image.once( 'error', deferred.reject ); + image.once( 'load', function() { + file._info = file._info || image.info(); + file._meta = file._meta || image.meta(); + image.resize( opts.width, opts.height ); + }); + + image.once( 'complete', function() { + var blob, size; + + // 绉诲姩绔� UC / qq 娴忚鍣ㄧ殑鏃犲浘妯″紡涓� + // ctx.getImageData 澶勭悊澶у浘鐨勬椂鍊欎細鎶� Exception + // INDEX_SIZE_ERR: DOM Exception 1 + try { + blob = image.getAsBlob( opts.type ); + + size = file.size; + + // 濡傛灉鍘嬬缉鍚庯紝姣斿師鏉ヨ繕澶у垯涓嶇敤鍘嬬缉鍚庣殑銆� + if ( blob.size < size ) { + // file.source.destroy && file.source.destroy(); + file.source = blob; + file.size = blob.size; + + file.trigger( 'resize', blob.size, size ); + } + + // 鏍囪锛岄伩鍏嶉噸澶嶅帇缂┿�� + file._compressed = true; + deferred.resolve(); + } catch ( e ) { + // 鍑洪敊浜嗙洿鎺ョ户缁紝璁╁叾涓婁紶鍘熷鍥剧墖 + deferred.resolve(); + } + }); + + file._info && image.info( file._info ); + file._meta && image.meta( file._meta ); + + image.loadFromBlob( file.source ); + return deferred.promise(); + } + }); + }); + /** + * @fileOverview 鏂囦欢灞炴�у皝瑁� + */ + define('file',[ + 'base', + 'mediator' + ], function( Base, Mediator ) { + + var $ = Base.$, + idPrefix = 'WU_FILE_', + idSuffix = 0, + rExt = /\.([^.]+)$/, + statusMap = {}; + + function gid() { + return idPrefix + idSuffix++; + } + + /** + * 鏂囦欢绫� + * @class File + * @constructor 鏋勯�犲嚱鏁� + * @grammar new File( source ) => File + * @param {Lib.File} source [lib.File](#Lib.File)瀹炰緥, 姝ource瀵硅薄鏄甫鏈塕untime淇℃伅鐨勩�� + */ + function WUFile( source ) { + + /** + * 鏂囦欢鍚嶏紝鍖呮嫭鎵╁睍鍚嶏紙鍚庣紑锛� + * @property name + * @type {string} + */ + this.name = source.name || 'Untitled'; + + /** + * 鏂囦欢浣撶Н锛堝瓧鑺傦級 + * @property size + * @type {uint} + * @default 0 + */ + this.size = source.size || 0; + + /** + * 鏂囦欢MIMETYPE绫诲瀷锛屼笌鏂囦欢绫诲瀷鐨勫搴斿叧绯昏鍙傝�僛http://t.cn/z8ZnFny](http://t.cn/z8ZnFny) + * @property type + * @type {string} + * @default 'application' + */ + this.type = source.type || 'application'; + + /** + * 鏂囦欢鏈�鍚庝慨鏀规棩鏈� + * @property lastModifiedDate + * @type {int} + * @default 褰撳墠鏃堕棿鎴� + */ + this.lastModifiedDate = source.lastModifiedDate || (new Date() * 1); + + /** + * 鏂囦欢ID锛屾瘡涓璞″叿鏈夊敮涓�ID锛屼笌鏂囦欢鍚嶆棤鍏� + * @property id + * @type {string} + */ + this.id = gid(); + + /** + * 鏂囦欢鎵╁睍鍚嶏紝閫氳繃鏂囦欢鍚嶈幏鍙栵紝渚嬪test.png鐨勬墿灞曞悕涓簆ng + * @property ext + * @type {string} + */ + this.ext = rExt.exec( this.name ) ? RegExp.$1 : ''; + + + /** + * 鐘舵�佹枃瀛楄鏄庛�傚湪涓嶅悓鐨剆tatus璇涓嬫湁涓嶅悓鐨勭敤閫斻�� + * @property statusText + * @type {string} + */ + this.statusText = ''; + + // 瀛樺偍鏂囦欢鐘舵�侊紝闃叉閫氳繃灞炴�х洿鎺ヤ慨鏀� + statusMap[ this.id ] = WUFile.Status.INITED; + + this.source = source; + this.loaded = 0; + + this.on( 'error', function( msg ) { + this.setStatus( WUFile.Status.ERROR, msg ); + }); + } + + $.extend( WUFile.prototype, { + + /** + * 璁剧疆鐘舵�侊紝鐘舵�佸彉鍖栨椂浼氳Е鍙慲change`浜嬩欢銆� + * @method setStatus + * @grammar setStatus( status[, statusText] ); + * @param {File.Status|String} status [鏂囦欢鐘舵�佸�糫(#WebUploader:File:File.Status) + * @param {String} [statusText=''] 鐘舵�佽鏄庯紝甯稿湪error鏃朵娇鐢紝鐢╤ttp, abort,server绛夋潵鏍囪鏄敱浜庝粈涔堝師鍥犲鑷存枃浠堕敊璇�� + */ + setStatus: function( status, text ) { + + var prevStatus = statusMap[ this.id ]; + + typeof text !== 'undefined' && (this.statusText = text); + + if ( status !== prevStatus ) { + statusMap[ this.id ] = status; + /** + * 鏂囦欢鐘舵�佸彉鍖� + * @event statuschange + */ + this.trigger( 'statuschange', status, prevStatus ); + } + + }, + + /** + * 鑾峰彇鏂囦欢鐘舵�� + * @return {File.Status} + * @example + 鏂囦欢鐘舵�佸叿浣撳寘鎷互涓嬪嚑绉嶇被鍨嬶細 + { + // 鍒濆鍖� + INITED: 0, + // 宸插叆闃熷垪 + QUEUED: 1, + // 姝e湪涓婁紶 + PROGRESS: 2, + // 涓婁紶鍑洪敊 + ERROR: 3, + // 涓婁紶鎴愬姛 + COMPLETE: 4, + // 涓婁紶鍙栨秷 + CANCELLED: 5 + } + */ + getStatus: function() { + return statusMap[ this.id ]; + }, + + /** + * 鑾峰彇鏂囦欢鍘熷淇℃伅銆� + * @return {*} + */ + getSource: function() { + return this.source; + }, + + destory: function() { + delete statusMap[ this.id ]; + } + }); + + Mediator.installTo( WUFile.prototype ); + + /** + * 鏂囦欢鐘舵�佸�硷紝鍏蜂綋鍖呮嫭浠ヤ笅鍑犵绫诲瀷锛� + * * `inited` 鍒濆鐘舵�� + * * `queued` 宸茬粡杩涘叆闃熷垪, 绛夊緟涓婁紶 + * * `progress` 涓婁紶涓� + * * `complete` 涓婁紶瀹屾垚銆� + * * `error` 涓婁紶鍑洪敊锛屽彲閲嶈瘯 + * * `interrupt` 涓婁紶涓柇锛屽彲缁紶銆� + * * `invalid` 鏂囦欢涓嶅悎鏍硷紝涓嶈兘閲嶈瘯涓婁紶銆備細鑷姩浠庨槦鍒椾腑绉婚櫎銆� + * * `cancelled` 鏂囦欢琚Щ闄ゃ�� + * @property {Object} Status + * @namespace File + * @class File + * @static + */ + WUFile.Status = { + INITED: 'inited', // 鍒濆鐘舵�� + QUEUED: 'queued', // 宸茬粡杩涘叆闃熷垪, 绛夊緟涓婁紶 + PROGRESS: 'progress', // 涓婁紶涓� + ERROR: 'error', // 涓婁紶鍑洪敊锛屽彲閲嶈瘯 + COMPLETE: 'complete', // 涓婁紶瀹屾垚銆� + CANCELLED: 'cancelled', // 涓婁紶鍙栨秷銆� + INTERRUPT: 'interrupt', // 涓婁紶涓柇锛屽彲缁紶銆� + INVALID: 'invalid' // 鏂囦欢涓嶅悎鏍硷紝涓嶈兘閲嶈瘯涓婁紶銆� + }; + + return WUFile; + }); + + /** + * @fileOverview 鏂囦欢闃熷垪 + */ + define('queue',[ + 'base', + 'mediator', + 'file' + ], function( Base, Mediator, WUFile ) { + + var $ = Base.$, + STATUS = WUFile.Status; + + /** + * 鏂囦欢闃熷垪, 鐢ㄦ潵瀛樺偍鍚勪釜鐘舵�佷腑鐨勬枃浠躲�� + * @class Queue + * @extends Mediator + */ + function Queue() { + + /** + * 缁熻鏂囦欢鏁般�� + * * `numOfQueue` 闃熷垪涓殑鏂囦欢鏁般�� + * * `numOfSuccess` 涓婁紶鎴愬姛鐨勬枃浠舵暟 + * * `numOfCancel` 琚Щ闄ょ殑鏂囦欢鏁� + * * `numOfProgress` 姝e湪涓婁紶涓殑鏂囦欢鏁� + * * `numOfUploadFailed` 涓婁紶閿欒鐨勬枃浠舵暟銆� + * * `numOfInvalid` 鏃犳晥鐨勬枃浠舵暟銆� + * @property {Object} stats + */ + this.stats = { + numOfQueue: 0, + numOfSuccess: 0, + numOfCancel: 0, + numOfProgress: 0, + numOfUploadFailed: 0, + numOfInvalid: 0 + }; + + // 涓婁紶闃熷垪锛屼粎鍖呮嫭绛夊緟涓婁紶鐨勬枃浠� + this._queue = []; + + // 瀛樺偍鎵�鏈夋枃浠� + this._map = {}; + } + + $.extend( Queue.prototype, { + + /** + * 灏嗘柊鏂囦欢鍔犲叆瀵归槦鍒楀熬閮� + * + * @method append + * @param {File} file 鏂囦欢瀵硅薄 + */ + append: function( file ) { + this._queue.push( file ); + this._fileAdded( file ); + return this; + }, + + /** + * 灏嗘柊鏂囦欢鍔犲叆瀵归槦鍒楀ご閮� + * + * @method prepend + * @param {File} file 鏂囦欢瀵硅薄 + */ + prepend: function( file ) { + this._queue.unshift( file ); + this._fileAdded( file ); + return this; + }, + + /** + * 鑾峰彇鏂囦欢瀵硅薄 + * + * @method getFile + * @param {String} fileId 鏂囦欢ID + * @return {File} + */ + getFile: function( fileId ) { + if ( typeof fileId !== 'string' ) { + return fileId; + } + return this._map[ fileId ]; + }, + + /** + * 浠庨槦鍒椾腑鍙栧嚭涓�涓寚瀹氱姸鎬佺殑鏂囦欢銆� + * @grammar fetch( status ) => File + * @method fetch + * @param {String} status [鏂囦欢鐘舵�佸�糫(#WebUploader:File:File.Status) + * @return {File} [File](#WebUploader:File) + */ + fetch: function( status ) { + var len = this._queue.length, + i, file; + + status = status || STATUS.QUEUED; + + for ( i = 0; i < len; i++ ) { + file = this._queue[ i ]; + + if ( status === file.getStatus() ) { + return file; + } + } + + return null; + }, + + /** + * 瀵归槦鍒楄繘琛屾帓搴忥紝鑳藉鎺у埗鏂囦欢涓婁紶椤哄簭銆� + * @grammar sort( fn ) => undefined + * @method sort + * @param {Function} fn 鎺掑簭鏂规硶 + */ + sort: function( fn ) { + if ( typeof fn === 'function' ) { + this._queue.sort( fn ); + } + }, + + /** + * 鑾峰彇鎸囧畾绫诲瀷鐨勬枃浠跺垪琛�, 鍒楄〃涓瘡涓�涓垚鍛樹负[File](#WebUploader:File)瀵硅薄銆� + * @grammar getFiles( [status1[, status2 ...]] ) => Array + * @method getFiles + * @param {String} [status] [鏂囦欢鐘舵�佸�糫(#WebUploader:File:File.Status) + */ + getFiles: function() { + var sts = [].slice.call( arguments, 0 ), + ret = [], + i = 0, + len = this._queue.length, + file; + + for ( ; i < len; i++ ) { + file = this._queue[ i ]; + + if ( sts.length && !~$.inArray( file.getStatus(), sts ) ) { + continue; + } + + ret.push( file ); + } + + return ret; + }, + + _fileAdded: function( file ) { + var me = this, + existing = this._map[ file.id ]; + + if ( !existing ) { + this._map[ file.id ] = file; + + file.on( 'statuschange', function( cur, pre ) { + me._onFileStatusChange( cur, pre ); + }); + } + + file.setStatus( STATUS.QUEUED ); + }, + + _onFileStatusChange: function( curStatus, preStatus ) { + var stats = this.stats; + + switch ( preStatus ) { + case STATUS.PROGRESS: + stats.numOfProgress--; + break; + + case STATUS.QUEUED: + stats.numOfQueue --; + break; + + case STATUS.ERROR: + stats.numOfUploadFailed--; + break; + + case STATUS.INVALID: + stats.numOfInvalid--; + break; + } + + switch ( curStatus ) { + case STATUS.QUEUED: + stats.numOfQueue++; + break; + + case STATUS.PROGRESS: + stats.numOfProgress++; + break; + + case STATUS.ERROR: + stats.numOfUploadFailed++; + break; + + case STATUS.COMPLETE: + stats.numOfSuccess++; + break; + + case STATUS.CANCELLED: + stats.numOfCancel++; + break; + + case STATUS.INVALID: + stats.numOfInvalid++; + break; + } + } + + }); + + Mediator.installTo( Queue.prototype ); + + return Queue; + }); + /** + * @fileOverview 闃熷垪 + */ + define('widgets/queue',[ + 'base', + 'uploader', + 'queue', + 'file', + 'lib/file', + 'runtime/client', + 'widgets/widget' + ], function( Base, Uploader, Queue, WUFile, File, RuntimeClient ) { + + var $ = Base.$, + rExt = /\.\w+$/, + Status = WUFile.Status; + + return Uploader.register({ + 'sort-files': 'sortFiles', + 'add-file': 'addFiles', + 'get-file': 'getFile', + 'fetch-file': 'fetchFile', + 'get-stats': 'getStats', + 'get-files': 'getFiles', + 'remove-file': 'removeFile', + 'retry': 'retry', + 'reset': 'reset', + 'accept-file': 'acceptFile' + }, { + + 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杩愯鏃讹紝閭e氨绠椾簡銆� + // 涓嶆墽琛屽悗缁搷浣� + if ( this.request('predict-runtime-type') !== 'html5' ) { + return; + } + + // 鍒涘缓涓�涓� html5 杩愯鏃剁殑 placeholder + // 浠ヨ嚦浜庡閮ㄦ坊鍔犲師鐢� File 瀵硅薄鐨勬椂鍊欒兘姝g‘鍖呰9涓�涓嬩緵 webuploader 浣跨敤銆� + deferred = Base.Deferred(); + runtime = new RuntimeClient('Placeholder'); + runtime.connectRuntime({ + runtimeOrder: 'html5' + }, function() { + me._ruid = runtime.getRuid(); + deferred.resolve(); + }); + return deferred.promise(); + }, + + + // 涓轰簡鏀寔澶栭儴鐩存帴娣诲姞涓�涓師鐢烣ile瀵硅薄銆� + _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 < 6 || this.accept && + + // 濡傛灉鍚嶅瓧涓湁鍚庣紑锛屾墠鍋氬悗缂�鐧藉悕鍗曞鐞嗐�� + rExt.exec( file.name ) && !this.accept.test( file.name ); + + return !invalid; + }, + + + /** + * @event beforeFileQueued + * @param {File} file File瀵硅薄 + * @description 褰撴枃浠惰鍔犲叆闃熷垪涔嬪墠瑙﹀彂锛屾浜嬩欢鐨刪andler杩斿洖鍊间负`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 + */ + + /** + * @method addFiles + * @grammar addFiles( file ) => undefined + * @grammar addFiles( [file1, file2 ...] ) => undefined + * @param {Array of File or File} [files] Files 瀵硅薄 鏁扮粍 + * @description 娣诲姞鏂囦欢鍒伴槦鍒� + * @for Uploader + */ + addFiles: function( files ) { + var me = this; + + if ( !files.length ) { + files = [ files ]; + } + + files = $.map( files, function( file ) { + return me._addFile( file ); + }); + + me.owner.trigger( 'filesQueued', files ); + + if ( me.options.auto ) { + me.request('start-upload'); + } + }, + + getStats: function() { + return this.stats; + }, + + /** + * @event fileDequeued + * @param {File} file File瀵硅薄 + * @description 褰撴枃浠惰绉婚櫎闃熷垪鍚庤Е鍙戙�� + * @for Uploader + */ + + /** + * @method removeFile + * @grammar removeFile( file ) => undefined + * @grammar removeFile( id ) => undefined + * @param {File|id} file File瀵硅薄鎴栬繖File瀵硅薄鐨刬d + * @description 绉婚櫎鏌愪竴鏂囦欢銆� + * @for Uploader + * @example + * + * $li.on('click', '.remove-this', function() { + * uploader.removeFile( file ); + * }) + */ + removeFile: function( file ) { + var me = this; + + file = file.id ? file : me.queue.getFile( file ); + + file.setStatus( Status.CANCELLED ); + me.owner.trigger( 'fileDequeued', 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 ); + }, + + /** + * @method reset + * @grammar reset() => undefined + * @description 閲嶇疆uploader銆傜洰鍓嶅彧閲嶇疆浜嗛槦鍒椼�� + * @for Uploader + * @example + * uploader.reset(); + */ + reset: function() { + this.queue = new Queue(); + this.stats = this.queue.stats; + } + }); + + }); + /** + * @fileOverview 娣诲姞鑾峰彇Runtime鐩稿叧淇℃伅鐨勬柟娉曘�� + */ + define('widgets/runtime',[ + 'uploader', + 'runtime/runtime', + 'widgets/widget' + ], function( Uploader, Runtime ) { + + Uploader.support = function() { + return Runtime.hasRuntime.apply( Runtime, arguments ); + }; + + return Uploader.register({ + 'predict-runtime-type': 'predictRuntmeType' + }, { + + init: function() { + if ( !this.predictRuntmeType() ) { + throw Error('Runtime Error'); + } + }, + + /** + * 棰勬祴Uploader灏嗛噰鐢ㄥ摢涓猔Runtime` + * @grammar predictRuntmeType() => String + * @method predictRuntmeType + * @for Uploader + */ + predictRuntmeType: function() { + var orders = this.options.runtimeOrder || Runtime.orders, + type = this.type, + i, len; + + if ( !type ) { + orders = orders.split( /\s*,\s*/g ); + + for ( i = 0, len = orders.length; i < len; i++ ) { + if ( Runtime.hasRuntime( orders[ i ] ) ) { + this.type = type = orders[ i ]; + break; + } + } + } + + return type; + } + }); + }); + /** + * @fileOverview Transport + */ + define('lib/transport',[ + 'base', + 'runtime/client', + 'mediator' + ], function( Base, RuntimeClient, Mediator ) { + + var $ = Base.$; + + function Transport( opts ) { + var me = this; + + opts = me.options = $.extend( true, {}, Transport.options, opts || {} ); + RuntimeClient.call( this, 'Transport' ); + + this._blob = null; + this._formData = opts.formData || {}; + this._headers = opts.headers || {}; + + this.on( 'progress', this._timeout ); + this.on( 'load error', function() { + me.trigger( 'progress', 1 ); + clearTimeout( me._timer ); + }); + } + + Transport.options = { + server: '', + method: 'POST', + + // 璺ㄥ煙鏃讹紝鏄惁鍏佽鎼哄甫cookie, 鍙湁html5 runtime鎵嶆湁鏁� + withCredentials: false, + fileVal: 'file', + timeout: 2 * 60 * 1000, // 2鍒嗛挓 + formData: {}, + headers: {}, + sendAsBinary: false + }; + + $.extend( Transport.prototype, { + + // 娣诲姞Blob, 鍙兘娣诲姞涓�娆★紝鏈�鍚庝竴娆℃湁鏁堛�� + appendBlob: function( key, blob, filename ) { + var me = this, + opts = me.options; + + if ( me.getRuid() ) { + me.disconnectRuntime(); + } + + // 杩炴帴鍒癰lob褰掑睘鐨勫悓涓�涓猺untime. + me.connectRuntime( blob.ruid, function() { + me.exec('init'); + }); + + me._blob = blob; + opts.fileVal = key || opts.fileVal; + opts.filename = filename || opts.filename; + }, + + // 娣诲姞鍏朵粬瀛楁 + append: function( key, value ) { + if ( typeof key === 'object' ) { + $.extend( this._formData, key ); + } else { + this._formData[ key ] = value; + } + }, + + setRequestHeader: function( key, value ) { + if ( typeof key === 'object' ) { + $.extend( this._headers, key ); + } else { + this._headers[ key ] = value; + } + }, + + send: function( method ) { + this.exec( 'send', method ); + this._timeout(); + }, + + abort: function() { + clearTimeout( this._timer ); + return this.exec('abort'); + }, + + destroy: function() { + this.trigger('destroy'); + this.off(); + this.exec('destroy'); + this.disconnectRuntime(); + }, + + getResponse: function() { + return this.exec('getResponse'); + }, + + getResponseAsJson: function() { + return this.exec('getResponseAsJson'); + }, + + getStatus: function() { + return this.exec('getStatus'); + }, + + _timeout: function() { + var me = this, + duration = me.options.timeout; + + if ( !duration ) { + return; + } + + clearTimeout( me._timer ); + me._timer = setTimeout(function() { + me.abort(); + me.trigger( 'error', 'timeout' ); + }, duration ); + } + + }); + + // 璁㏕ransport鍏峰浜嬩欢鍔熻兘銆� + Mediator.installTo( Transport.prototype ); + + return Transport; + }); + /** + * @fileOverview 璐熻矗鏂囦欢涓婁紶鐩稿叧銆� + */ + define('widgets/upload',[ + 'base', + 'uploader', + 'file', + 'lib/transport', + 'widgets/widget' + ], function( Base, Uploader, WUFile, Transport ) { + + var $ = Base.$, + isPromise = Base.isPromise, + Status = WUFile.Status; + + // 娣诲姞榛樿閰嶇疆椤� + $.extend( Uploader.options, { + + + /** + * @property {Boolean} [prepareNextFile=false] + * @namespace options + * @for Uploader + * @description 鏄惁鍏佽鍦ㄦ枃浠朵紶杈撴椂鎻愬墠鎶婁笅涓�涓枃浠跺噯澶囧ソ銆� + * 瀵逛簬涓�涓枃浠剁殑鍑嗗宸ヤ綔姣旇緝鑰楁椂锛屾瘮濡傚浘鐗囧帇缂╋紝md5搴忓垪鍖栥�� + * 濡傛灉鑳芥彁鍓嶅湪褰撳墠鏂囦欢浼犺緭鏈熷鐞嗭紝鍙互鑺傜渷鎬讳綋鑰楁椂銆� + */ + prepareNextFile: false, + + /** + * @property {Boolean} [chunked=false] + * @namespace options + * @for Uploader + * @description 鏄惁瑕佸垎鐗囧鐞嗗ぇ鏂囦欢涓婁紶銆� + */ + chunked: false, + + /** + * @property {Boolean} [chunkSize=5242880] + * @namespace options + * @for Uploader + * @description 濡傛灉瑕佸垎鐗囷紝鍒嗗澶т竴鐗囷紵 榛樿澶у皬涓�5M. + */ + chunkSize: 5 * 1024 * 1024, + + /** + * @property {Boolean} [chunkRetry=2] + * @namespace options + * @for Uploader + * @description 濡傛灉鏌愪釜鍒嗙墖鐢变簬缃戠粶闂鍑洪敊锛屽厑璁歌嚜鍔ㄩ噸浼犲灏戞锛� + */ + chunkRetry: 2, + + /** + * @property {Boolean} [threads=3] + * @namespace options + * @for Uploader + * @description 涓婁紶骞跺彂鏁般�傚厑璁稿悓鏃舵渶澶т笂浼犺繘绋嬫暟銆� + */ + threads: 3, + + + /** + * @property {Object} [formData] + * @namespace options + * @for Uploader + * @description 鏂囦欢涓婁紶璇锋眰鐨勫弬鏁拌〃锛屾瘡娆″彂閫侀兘浼氬彂閫佹瀵硅薄涓殑鍙傛暟銆� + */ + formData: null + + /** + * @property {Object} [fileVal='file'] + * @namespace options + * @for Uploader + * @description 璁剧疆鏂囦欢涓婁紶鍩熺殑name銆� + */ + + /** + * @property {Object} [method='POST'] + * @namespace options + * @for Uploader + * @description 鏂囦欢涓婁紶鏂瑰紡锛宍POST`鎴栬�卄GET`銆� + */ + + /** + * @property {Object} [sendAsBinary=false] + * @namespace options + * @for Uploader + * @description 鏄惁宸蹭簩杩涘埗鐨勬祦鐨勬柟寮忓彂閫佹枃浠讹紝杩欐牱鏁翠釜涓婁紶鍐呭`php://input`閮戒负鏂囦欢鍐呭锛� + * 鍏朵粬鍙傛暟鍦�$_GET鏁扮粍涓�� + */ + }); + + // 璐熻矗灏嗘枃浠跺垏鐗囥�� + function CuteFile( file, chunkSize ) { + var pending = [], + blob = file.source, + total = blob.size, + chunks = chunkSize ? Math.ceil( total / chunkSize ) : 1, + start = 0, + index = 0, + len; + + while ( index < chunks ) { + len = Math.min( chunkSize, total - start ); + + pending.push({ + file: file, + start: start, + end: chunkSize ? (start + len) : total, + total: total, + chunks: chunks, + chunk: index++ + }); + start += len; + } + + file.blocks = pending.concat(); + file.remaning = pending.length; + + return { + file: file, + + has: function() { + return !!pending.length; + }, + + fetch: function() { + return pending.shift(); + } + }; + } + + Uploader.register({ + 'start-upload': 'start', + 'stop-upload': 'stop', + 'skip-file': 'skipFile', + 'is-in-progress': 'isInProgress' + }, { + + init: function() { + var owner = this.owner; + + this.runing = false; + + // 璁板綍褰撳墠姝e湪浼犵殑鏁版嵁锛岃窡threads鐩稿叧 + this.pool = []; + + // 缂撳瓨鍗冲皢涓婁紶鐨勬枃浠躲�� + this.pending = []; + + // 璺熻釜杩樻湁澶氬皯鍒嗙墖娌℃湁瀹屾垚涓婁紶銆� + this.remaning = 0; + this.__tick = Base.bindFn( this._tick, this ); + + owner.on( 'uploadComplete', function( file ) { + // 鎶婂叾浠栧潡鍙栨秷浜嗐�� + file.blocks && $.each( file.blocks, function( _, v ) { + v.transport && (v.transport.abort(), v.transport.destroy()); + delete v.transport; + }); + + delete file.blocks; + delete file.remaning; + }); + }, + + /** + * @event startUpload + * @description 褰撳紑濮嬩笂浼犳祦绋嬫椂瑙﹀彂銆� + * @for Uploader + */ + + /** + * 寮�濮嬩笂浼犮�傛鏂规硶鍙互浠庡垵濮嬬姸鎬佽皟鐢ㄥ紑濮嬩笂浼犳祦绋嬶紝涔熷彲浠ヤ粠鏆傚仠鐘舵�佽皟鐢紝缁х画涓婁紶娴佺▼銆� + * @grammar upload() => undefined + * @method upload + * @for Uploader + */ + start: function() { + var me = this; + + // 绉诲嚭invalid鐨勬枃浠� + $.each( me.request( 'get-files', Status.INVALID ), function() { + me.request( 'remove-file', this ); + }); + + if ( me.runing ) { + return; + } + + me.runing = true; + + // 濡傛灉鏈夋殏鍋滅殑锛屽垯缁紶 + $.each( me.pool, function( _, v ) { + var file = v.file; + + if ( file.getStatus() === Status.INTERRUPT ) { + file.setStatus( Status.PROGRESS ); + me._trigged = false; + v.transport && v.transport.send(); + } + }); + + me._trigged = false; + me.owner.trigger('startUpload'); + Base.nextTick( me.__tick ); + }, + + /** + * @event stopUpload + * @description 褰撳紑濮嬩笂浼犳祦绋嬫殏鍋滄椂瑙﹀彂銆� + * @for Uploader + */ + + /** + * 鏆傚仠涓婁紶銆傜涓�涓弬鏁颁负鏄惁涓柇涓婁紶褰撳墠姝e湪涓婁紶鐨勬枃浠躲�� + * @grammar stop() => undefined + * @grammar stop( true ) => undefined + * @method stop + * @for Uploader + */ + stop: function( interrupt ) { + var me = this; + + if ( me.runing === false ) { + return; + } + + me.runing = false; + + interrupt && $.each( me.pool, function( _, v ) { + v.transport && v.transport.abort(); + v.file.setStatus( Status.INTERRUPT ); + }); + + me.owner.trigger('stopUpload'); + }, + + /** + * 鍒ゆ柇`Uplaode`r鏄惁姝e湪涓婁紶涓�� + * @grammar isInProgress() => Boolean + * @method isInProgress + * @for Uploader + */ + isInProgress: function() { + return !!this.runing; + }, + + getStats: function() { + return this.request('get-stats'); + }, + + /** + * 鎺夎繃涓�涓枃浠朵笂浼狅紝鐩存帴鏍囪鎸囧畾鏂囦欢涓哄凡涓婁紶鐘舵�併�� + * @grammar skipFile( file ) => undefined + * @method skipFile + * @for Uploader + */ + skipFile: function( file, status ) { + file = this.request( 'get-file', file ); + + file.setStatus( status || Status.COMPLETE ); + file.skipped = true; + + // 濡傛灉姝e湪涓婁紶銆� + file.blocks && $.each( file.blocks, function( _, v ) { + var _tr = v.transport; + + if ( _tr ) { + _tr.abort(); + _tr.destroy(); + delete v.transport; + } + }); + + this.owner.trigger( 'uploadSkip', file ); + }, + + /** + * @event uploadFinished + * @description 褰撴墍鏈夋枃浠朵笂浼犵粨鏉熸椂瑙﹀彂銆� + * @for Uploader + */ + _tick: function() { + var me = this, + opts = me.options, + fn, val; + + // 涓婁竴涓猵romise杩樻病鏈夌粨鏉燂紝鍒欑瓑寰呭畬鎴愬悗鍐嶆墽琛屻�� + if ( me._promise ) { + return me._promise.always( me.__tick ); + } + + // 杩樻湁浣嶇疆锛屼笖杩樻湁鏂囦欢瑕佸鐞嗙殑璇濄�� + if ( me.pool.length < opts.threads && (val = me._nextBlock()) ) { + me._trigged = false; + + fn = function( val ) { + me._promise = null; + + // 鏈夊彲鑳芥槸reject杩囨潵鐨勶紝鎵�浠ヨ妫�娴媣al鐨勭被鍨嬨�� + val && val.file && me._startSend( val ); + Base.nextTick( me.__tick ); + }; + + me._promise = isPromise( val ) ? val.always( fn ) : fn( val ); + + // 娌℃湁瑕佷笂浼犵殑浜嗭紝涓旀病鏈夋鍦ㄤ紶杈撶殑浜嗐�� + } else if ( !me.remaning && !me.getStats().numOfQueue ) { + me.runing = false; + + me._trigged || Base.nextTick(function() { + me.owner.trigger('uploadFinished'); + }); + me._trigged = true; + } + }, + + _nextBlock: function() { + var me = this, + act = me._act, + opts = me.options, + next, done; + + // 濡傛灉褰撳墠鏂囦欢杩樻湁娌℃湁闇�瑕佷紶杈撶殑锛屽垯鐩存帴杩斿洖鍓╀笅鐨勩�� + if ( act && act.has() && + act.file.getStatus() === Status.PROGRESS ) { + + // 鏄惁鎻愬墠鍑嗗涓嬩竴涓枃浠� + if ( opts.prepareNextFile && !me.pending.length ) { + me._prepareNextFile(); + } + + return act.fetch(); + + // 鍚﹀垯锛屽鏋滄鍦ㄨ繍琛岋紝鍒欏噯澶囦笅涓�涓枃浠讹紝骞剁瓑寰呭畬鎴愬悗杩斿洖涓嬩釜鍒嗙墖銆� + } else if ( me.runing ) { + + // 濡傛灉缂撳瓨涓湁锛屽垯鐩存帴鍦ㄧ紦瀛樹腑鍙栵紝娌℃湁鍒欏幓queue涓彇銆� + if ( !me.pending.length && me.getStats().numOfQueue ) { + me._prepareNextFile(); + } + + next = me.pending.shift(); + done = function( file ) { + if ( !file ) { + return null; + } + + act = CuteFile( file, opts.chunked ? opts.chunkSize : 0 ); + me._act = act; + return act.fetch(); + }; + + // 鏂囦欢鍙兘杩樺湪prepare涓紝涔熸湁鍙兘宸茬粡瀹屽叏鍑嗗濂戒簡銆� + return isPromise( next ) ? + next[ next.pipe ? 'pipe' : 'then']( done ) : + done( next ); + } + }, + + + /** + * @event uploadStart + * @param {File} file File瀵硅薄 + * @description 鏌愪釜鏂囦欢寮�濮嬩笂浼犲墠瑙﹀彂锛屼竴涓枃浠跺彧浼氳Е鍙戜竴娆°�� + * @for Uploader + */ + _prepareNextFile: function() { + var me = this, + file = me.request('fetch-file'), + pending = me.pending, + promise; + + if ( file ) { + promise = me.request( 'before-send-file', file, function() { + + // 鏈夊彲鑳芥枃浠惰skip鎺変簡銆傛枃浠惰skip鎺夊悗锛岀姸鎬佸潙瀹氫笉鏄疩ueued. + if ( file.getStatus() === Status.QUEUED ) { + me.owner.trigger( 'uploadStart', file ); + file.setStatus( Status.PROGRESS ); + return file; + } + + return me._finishFile( file ); + }); + + // 濡傛灉杩樺湪pending涓紝鍒欐浛鎹㈡垚鏂囦欢鏈韩銆� + promise.done(function() { + var idx = $.inArray( promise, pending ); + + ~idx && pending.splice( idx, 1, file ); + }); + + // befeore-send-file鐨勯挬瀛愬氨鏈夐敊璇彂鐢熴�� + promise.fail(function( reason ) { + file.setStatus( Status.ERROR, reason ); + me.owner.trigger( 'uploadError', file, reason ); + me.owner.trigger( 'uploadComplete', file ); + }); + + pending.push( promise ); + } + }, + + // 璁╁嚭浣嶇疆浜嗭紝鍙互璁╁叾浠栧垎鐗囧紑濮嬩笂浼� + _popBlock: function( block ) { + var idx = $.inArray( block, this.pool ); + + this.pool.splice( idx, 1 ); + block.file.remaning--; + this.remaning--; + }, + + // 寮�濮嬩笂浼狅紝鍙互琚帀杩囥�傚鏋減romise琚玶eject浜嗭紝鍒欒〃绀鸿烦杩囨鍒嗙墖銆� + _startSend: function( block ) { + var me = this, + file = block.file, + promise; + + me.pool.push( block ); + me.remaning++; + + // 濡傛灉娌℃湁鍒嗙墖锛屽垯鐩存帴浣跨敤鍘熷鐨勩�� + // 涓嶄細涓㈠けcontent-type淇℃伅銆� + block.blob = block.chunks === 1 ? file.source : + file.source.slice( block.start, block.end ); + + // hook, 姣忎釜鍒嗙墖鍙戦�佷箣鍓嶅彲鑳借鍋氫簺寮傛鐨勪簨鎯呫�� + promise = me.request( 'before-send', block, function() { + + // 鏈夊彲鑳芥枃浠跺凡缁忎笂浼犲嚭閿欎簡锛屾墍浠ヤ笉闇�瑕佸啀浼犺緭浜嗐�� + if ( file.getStatus() === Status.PROGRESS ) { + me._doSend( block ); + } else { + me._popBlock( block ); + Base.nextTick( me.__tick ); + } + }); + + // 濡傛灉涓篺ail浜嗭紝鍒欒烦杩囨鍒嗙墖銆� + promise.fail(function() { + if ( file.remaning === 1 ) { + me._finishFile( file ).always(function() { + block.percentage = 1; + me._popBlock( block ); + me.owner.trigger( 'uploadComplete', file ); + Base.nextTick( me.__tick ); + }); + } else { + block.percentage = 1; + me._popBlock( block ); + Base.nextTick( me.__tick ); + } + }); + }, + + + /** + * @event uploadBeforeSend + * @param {Object} object + * @param {Object} data 榛樿鐨勪笂浼犲弬鏁帮紝鍙互鎵╁睍姝ゅ璞℃潵鎺у埗涓婁紶鍙傛暟銆� + * @description 褰撴煇涓枃浠剁殑鍒嗗潡鍦ㄥ彂閫佸墠瑙﹀彂锛屼富瑕佺敤鏉ヨ闂槸鍚﹁娣诲姞闄勫甫鍙傛暟锛屽ぇ鏂囦欢鍦ㄥ紑璧峰垎鐗囦笂浼犵殑鍓嶆彁涓嬫浜嬩欢鍙兘浼氳Е鍙戝娆°�� + * @for Uploader + */ + + /** + * @event uploadAccept + * @param {Object} object + * @param {Object} ret 鏈嶅姟绔殑杩斿洖鏁版嵁锛宩son鏍煎紡锛屽鏋滄湇鍔$涓嶆槸json鏍煎紡锛屼粠ret._raw涓彇鏁版嵁锛岃嚜琛岃В鏋愩�� + * @description 褰撴煇涓枃浠朵笂浼犲埌鏈嶅姟绔搷搴斿悗锛屼細娲鹃�佹浜嬩欢鏉ヨ闂湇鍔$鍝嶅簲鏄惁鏈夋晥銆傚鏋滄浜嬩欢handler杩斿洖鍊间负`false`, 鍒欐鏂囦欢灏嗘淳閫乣server`绫诲瀷鐨刞uploadError`浜嬩欢銆� + * @for Uploader + */ + + /** + * @event uploadProgress + * @param {File} file File瀵硅薄 + * @param {Number} percentage 涓婁紶杩涘害 + * @description 涓婁紶杩囩▼涓Е鍙戯紝鎼哄甫涓婁紶杩涘害銆� + * @for Uploader + */ + + + /** + * @event uploadError + * @param {File} file File瀵硅薄 + * @param {String} reason 鍑洪敊鐨刢ode + * @description 褰撴枃浠朵笂浼犲嚭閿欐椂瑙﹀彂銆� + * @for Uploader + */ + + /** + * @event uploadSuccess + * @param {File} file File瀵硅薄 + * @param {Object} response 鏈嶅姟绔繑鍥炵殑鏁版嵁 + * @description 褰撴枃浠朵笂浼犳垚鍔熸椂瑙﹀彂銆� + * @for Uploader + */ + + /** + * @event uploadComplete + * @param {File} [file] File瀵硅薄 + * @description 涓嶇鎴愬姛鎴栬�呭け璐ワ紝鏂囦欢涓婁紶瀹屾垚鏃惰Е鍙戙�� + * @for Uploader + */ + + // 鍋氫笂浼犳搷浣溿�� + _doSend: function( block ) { + var me = this, + owner = me.owner, + opts = me.options, + file = block.file, + tr = new Transport( opts ), + data = $.extend({}, opts.formData ), + headers = $.extend({}, opts.headers ), + requestAccept, ret; + + block.transport = tr; + + tr.on( 'destroy', function() { + delete block.transport; + me._popBlock( block ); + Base.nextTick( me.__tick ); + }); + + // 骞挎挱涓婁紶杩涘害銆備互鏂囦欢涓哄崟浣嶃�� + tr.on( 'progress', function( percentage ) { + var totalPercent = 0, + uploaded = 0; + + // 鍙兘娌℃湁abort鎺夛紝progress杩樻槸鎵ц杩涙潵浜嗐�� + // if ( !file.blocks ) { + // return; + // } + + totalPercent = block.percentage = percentage; + + if ( block.chunks > 1 ) { // 璁$畻鏂囦欢鐨勬暣浣撻�熷害銆� + $.each( file.blocks, function( _, v ) { + uploaded += (v.percentage || 0) * (v.end - v.start); + }); + + totalPercent = uploaded / file.size; + } + + owner.trigger( 'uploadProgress', file, totalPercent || 0 ); + }); + + // 鐢ㄦ潵璇㈤棶锛屾槸鍚﹁繑鍥炵殑缁撴灉鏄湁閿欒鐨勩�� + requestAccept = function( reject ) { + var fn; + + ret = tr.getResponseAsJson() || {}; + ret._raw = tr.getResponse(); + fn = function( value ) { + reject = value; + }; + + // 鏈嶅姟绔搷搴斾簡锛屼笉浠h〃鎴愬姛浜嗭紝璇㈤棶鏄惁鍝嶅簲姝g‘銆� + if ( !owner.trigger( 'uploadAccept', block, ret, fn ) ) { + reject = reject || 'server'; + } + + return reject; + }; + + // 灏濊瘯閲嶈瘯锛岀劧鍚庡箍鎾枃浠朵笂浼犲嚭閿欍�� + tr.on( 'error', function( type, flag ) { + block.retried = block.retried || 0; + + // 鑷姩閲嶈瘯 + if ( block.chunks > 1 && ~'http,abort'.indexOf( type ) && + block.retried < opts.chunkRetry ) { + + block.retried++; + tr.send(); + + } else { + + // http status 500 ~ 600 + if ( !flag && type === 'server' ) { + type = requestAccept( type ); + } + + file.setStatus( Status.ERROR, type ); + owner.trigger( 'uploadError', file, type ); + owner.trigger( 'uploadComplete', file ); + } + }); + + // 涓婁紶鎴愬姛 + tr.on( 'load', function() { + var reason; + + // 濡傛灉闈為鏈燂紝杞悜涓婁紶鍑洪敊銆� + if ( (reason = requestAccept()) ) { + tr.trigger( 'error', reason, true ); + return; + } + + // 鍏ㄩ儴涓婁紶瀹屾垚銆� + if ( file.remaning === 1 ) { + me._finishFile( file, ret ); + } else { + tr.destroy(); + } + }); + + // 閰嶇疆榛樿鐨勪笂浼犲瓧娈点�� + data = $.extend( data, { + id: file.id, + name: file.name, + type: file.type, + lastModifiedDate: file.lastModifiedDate, + size: file.size + }); + + block.chunks > 1 && $.extend( data, { + chunks: block.chunks, + chunk: block.chunk + }); + + // 鍦ㄥ彂閫佷箣闂村彲浠ユ坊鍔犲瓧娈典粈涔堢殑銆傘�傘�� + // 濡傛灉榛樿鐨勫瓧娈典笉澶熶娇鐢紝鍙互閫氳繃鐩戝惉姝や簨浠舵潵鎵╁睍 + owner.trigger( 'uploadBeforeSend', block, data, headers ); + + // 寮�濮嬪彂閫併�� + tr.appendBlob( opts.fileVal, block.blob, file.name ); + tr.append( data ); + tr.setRequestHeader( headers ); + tr.send(); + }, + + // 瀹屾垚涓婁紶銆� + _finishFile: function( file, ret, hds ) { + var owner = this.owner; + + return owner + .request( 'after-send-file', arguments, function() { + file.setStatus( Status.COMPLETE ); + owner.trigger( 'uploadSuccess', file, ret, hds ); + }) + .fail(function( reason ) { + + // 濡傛灉澶栭儴宸茬粡鏍囪涓篿nvalid浠�涔堢殑锛屼笉鍐嶆敼鐘舵�併�� + if ( file.getStatus() === Status.PROGRESS ) { + file.setStatus( Status.ERROR, reason ); + } + + owner.trigger( 'uploadError', file, reason ); + }) + .always(function() { + owner.trigger( 'uploadComplete', file ); + }); + } + + }); + }); + /** + * @fileOverview 鍚勭楠岃瘉锛屽寘鎷枃浠舵�诲ぇ灏忔槸鍚﹁秴鍑恒�佸崟鏂囦欢鏄惁瓒呭嚭鍜屾枃浠舵槸鍚﹂噸澶嶃�� + */ + + define('widgets/validator',[ + 'base', + 'uploader', + 'file', + 'widgets/widget' + ], function( Base, Uploader, WUFile ) { + + var $ = Base.$, + validators = {}, + api; + + /** + * @event error + * @param {String} type 閿欒绫诲瀷銆� + * @description 褰搗alidate涓嶉�氳繃鏃讹紝浼氫互娲鹃�侀敊璇簨浠剁殑褰㈠紡閫氱煡璋冪敤鑰呫�傞�氳繃`upload.on('error', handler)`鍙互鎹曡幏鍒版绫婚敊璇紝鐩墠鏈変互涓嬮敊璇細鍦ㄧ壒瀹氱殑鎯呭喌涓嬫淳閫侀敊鏉ャ�� + * + * * `Q_EXCEED_NUM_LIMIT` 鍦ㄨ缃簡`fileNumLimit`涓斿皾璇曠粰`uploader`娣诲姞鐨勬枃浠舵暟閲忚秴鍑鸿繖涓�兼椂娲鹃�併�� + * * `Q_EXCEED_SIZE_LIMIT` 鍦ㄨ缃簡`Q_EXCEED_SIZE_LIMIT`涓斿皾璇曠粰`uploader`娣诲姞鐨勬枃浠舵�诲ぇ灏忚秴鍑鸿繖涓�兼椂娲鹃�併�� + * @for Uploader + */ + + // 鏆撮湶缁欏闈㈢殑api + api = { + + // 娣诲姞楠岃瘉鍣� + addValidator: function( type, cb ) { + validators[ type ] = cb; + }, + + // 绉婚櫎楠岃瘉鍣� + removeValidator: function( type ) { + delete validators[ type ]; + } + }; + + // 鍦║ploader鍒濆鍖栫殑鏃跺�欏惎鍔╒alidators鐨勫垵濮嬪寲 + Uploader.register({ + init: function() { + var me = this; + $.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 = opts.fileNumLimit >> 0, + 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( 'uploadFinished', 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 = opts.fileSizeLimit >> 0, + 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( 'uploadFinished', 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', file ); + return false; + } + + }); + + }); + + /** + * @property {int} [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 ]); + }); + }); + + return api; + }); + + /** + * @fileOverview Runtime绠$悊鍣紝璐熻矗Runtime鐨勯�夋嫨, 杩炴帴 + */ + define('runtime/compbase',[],function() { + + function CompBase( owner, runtime ) { + + this.owner = owner; + this.options = owner.options; + + this.getRuntime = function() { + return runtime; + }; + + this.getRuid = function() { + return runtime.uid; + }; + + this.trigger = function() { + return owner.trigger.apply( owner, arguments ); + }; + } + + return CompBase; + }); + /** + * @fileOverview Html5Runtime + */ + define('runtime/html5/runtime',[ + 'base', + 'runtime/runtime', + 'runtime/compbase' + ], function( Base, Runtime, CompBase ) { + + var type = 'html5', + components = {}; + + function Html5Runtime() { + var pool = {}, + me = this, + destory = this.destory; + + Runtime.apply( me, arguments ); + me.type = type; + + + // 杩欎釜鏂规硶鐨勮皟鐢ㄨ�咃紝瀹為檯涓婃槸RuntimeClient + me.exec = function( comp, fn/*, args...*/) { + var client = this, + uid = client.uid, + args = Base.slice( arguments, 2 ), + instance; + + if ( components[ comp ] ) { + instance = pool[ uid ] = pool[ uid ] || + new components[ comp ]( client, me ); + + if ( instance[ fn ] ) { + return instance[ fn ].apply( instance, args ); + } + } + }; + + me.destory = function() { + // @todo 鍒犻櫎姹犲瓙涓殑鎵�鏈夊疄渚� + return destory && destory.apply( this, arguments ); + }; + } + + Base.inherits( Runtime, { + constructor: Html5Runtime, + + // 涓嶉渶瑕佽繛鎺ュ叾浠栫▼搴忥紝鐩存帴鎵цcallback + init: function() { + var me = this; + setTimeout(function() { + me.trigger('ready'); + }, 1 ); + } + + }); + + // 娉ㄥ唽Components + Html5Runtime.register = function( name, component ) { + var klass = components[ name ] = Base.inherits( CompBase, component ); + return klass; + }; + + // 娉ㄥ唽html5杩愯鏃躲�� + // 鍙湁鍦ㄦ敮鎸佺殑鍓嶆彁涓嬫敞鍐屻�� + if ( window.Blob && window.FileReader && window.DataView ) { + Runtime.addRuntime( type, Html5Runtime ); + } + + return Html5Runtime; + }); + /** + * @fileOverview Blob Html瀹炵幇 + */ + define('runtime/html5/blob',[ + 'runtime/html5/runtime', + 'lib/blob' + ], function( Html5Runtime, Blob ) { + + return Html5Runtime.register( 'Blob', { + slice: function( start, end ) { + var blob = this.owner.source, + slice = blob.slice || blob.webkitSlice || blob.mozSlice; + + blob = slice.call( blob, start, end ); + + return new Blob( this.getRuid(), blob ); + } + }); + }); + /** + * @fileOverview FilePaste + */ + define('runtime/html5/dnd',[ + 'base', + 'runtime/html5/runtime', + 'lib/file' + ], function( Base, Html5Runtime, File ) { + + var $ = Base.$, + prefix = 'webuploader-dnd-'; + + return Html5Runtime.register( 'DragAndDrop', { + init: function() { + var elem = this.elem = this.options.container; + + this.dragEnterHandler = Base.bindFn( this._dragEnterHandler, this ); + this.dragOverHandler = Base.bindFn( this._dragOverHandler, this ); + this.dragLeaveHandler = Base.bindFn( this._dragLeaveHandler, this ); + this.dropHandler = Base.bindFn( this._dropHandler, this ); + this.dndOver = false; + + elem.on( 'dragenter', this.dragEnterHandler ); + elem.on( 'dragover', this.dragOverHandler ); + elem.on( 'dragleave', this.dragLeaveHandler ); + elem.on( 'drop', this.dropHandler ); + + if ( this.options.disableGlobalDnd ) { + $( document ).on( 'dragover', this.dragOverHandler ); + $( document ).on( 'drop', this.dropHandler ); + } + }, + + _dragEnterHandler: function( e ) { + var me = this, + denied = me._denied || false, + items; + + e = e.originalEvent || e; + + if ( !me.dndOver ) { + me.dndOver = true; + + // 娉ㄦ剰鍙湁 chrome 鏀寔銆� + items = e.dataTransfer.items; + + if ( items && items.length ) { + me._denied = denied = !me.trigger( 'accept', items ); + } + + me.elem.addClass( prefix + 'over' ); + me.elem[ denied ? 'addClass' : + 'removeClass' ]( prefix + 'denied' ); + } + + + e.dataTransfer.dropEffect = denied ? 'none' : 'copy'; + + return false; + }, + + _dragOverHandler: function( e ) { + // 鍙鐞嗘鍐呯殑銆� + var parentElem = this.elem.parent().get( 0 ); + if ( parentElem && !$.contains( parentElem, e.currentTarget ) ) { + return false; + } + + clearTimeout( this._leaveTimer ); + this._dragEnterHandler.call( this, e ); + + return false; + }, + + _dragLeaveHandler: function() { + var me = this, + handler; + + handler = function() { + me.dndOver = false; + me.elem.removeClass( prefix + 'over ' + prefix + 'denied' ); + }; + + clearTimeout( me._leaveTimer ); + me._leaveTimer = setTimeout( handler, 100 ); + return false; + }, + + _dropHandler: function( e ) { + var me = this, + ruid = me.getRuid(), + parentElem = me.elem.parent().get( 0 ); + + // 鍙鐞嗘鍐呯殑銆� + if ( parentElem && !$.contains( parentElem, e.currentTarget ) ) { + return false; + } + + me._getTansferFiles( e, function( results ) { + me.trigger( 'drop', $.map( results, function( file ) { + return new File( ruid, file ); + }) ); + }); + + me.dndOver = false; + me.elem.removeClass( prefix + 'over' ); + return false; + }, + + // 濡傛灉浼犲叆 callback 鍒欏幓鏌ョ湅鏂囦欢澶癸紝鍚﹀垯鍙褰撳墠鏂囦欢澶广�� + _getTansferFiles: function( e, callback ) { + var results = [], + promises = [], + items, files, dataTransfer, file, item, i, len, canAccessFolder; + + e = e.originalEvent || e; + + dataTransfer = e.dataTransfer; + items = dataTransfer.items; + files = dataTransfer.files; + + canAccessFolder = !!(items && items[ 0 ].webkitGetAsEntry); + + for ( i = 0, len = files.length; i < len; i++ ) { + file = files[ i ]; + item = items && items[ i ]; + + if ( canAccessFolder && item.webkitGetAsEntry().isDirectory ) { + + promises.push( this._traverseDirectoryTree( + item.webkitGetAsEntry(), results ) ); + } else { + results.push( file ); + } + } + + Base.when.apply( Base, promises ).done(function() { + + if ( !results.length ) { + return; + } + + callback( results ); + }); + }, + + _traverseDirectoryTree: function( entry, results ) { + var deferred = Base.Deferred(), + me = this; + + if ( entry.isFile ) { + entry.file(function( file ) { + results.push( file ); + deferred.resolve(); + }); + } else if ( entry.isDirectory ) { + entry.createReader().readEntries(function( entries ) { + var len = entries.length, + promises = [], + arr = [], // 涓轰簡淇濊瘉椤哄簭銆� + i; + + for ( i = 0; i < len; i++ ) { + promises.push( me._traverseDirectoryTree( + entries[ i ], arr ) ); + } + + Base.when.apply( Base, promises ).then(function() { + results.push.apply( results, arr ); + deferred.resolve(); + }, deferred.reject ); + }); + } + + return deferred.promise(); + }, + + destroy: function() { + var elem = this.elem; + + elem.off( 'dragenter', this.dragEnterHandler ); + elem.off( 'dragover', this.dragEnterHandler ); + elem.off( 'dragleave', this.dragLeaveHandler ); + elem.off( 'drop', this.dropHandler ); + + if ( this.options.disableGlobalDnd ) { + $( document ).off( 'dragover', this.dragOverHandler ); + $( document ).off( 'drop', this.dropHandler ); + } + } + }); + }); + + /** + * @fileOverview FilePaste + */ + define('runtime/html5/filepaste',[ + 'base', + 'runtime/html5/runtime', + 'lib/file' + ], function( Base, Html5Runtime, File ) { + + return Html5Runtime.register( 'FilePaste', { + init: function() { + var opts = this.options, + elem = this.elem = opts.container, + accept = '.*', + arr, i, len, item; + + // accetp鐨刴imeTypes涓敓鎴愬尮閰嶆鍒欍�� + if ( opts.accept ) { + arr = []; + + for ( i = 0, len = opts.accept.length; i < len; i++ ) { + item = opts.accept[ i ].mimeTypes; + item && arr.push( item ); + } + + if ( arr.length ) { + accept = arr.join(','); + accept = accept.replace( /,/g, '|' ).replace( /\*/g, '.*' ); + } + } + this.accept = accept = new RegExp( accept, 'i' ); + this.hander = Base.bindFn( this._pasteHander, this ); + elem.on( 'paste', this.hander ); + }, + + _pasteHander: function( e ) { + var allowed = [], + ruid = this.getRuid(), + items, item, blob, i, len; + + e = e.originalEvent || e; + items = e.clipboardData.items; + + for ( i = 0, len = items.length; i < len; i++ ) { + item = items[ i ]; + + if ( item.kind !== 'file' || !(blob = item.getAsFile()) ) { + continue; + } + + allowed.push( new File( ruid, blob ) ); + } + + if ( allowed.length ) { + // 涓嶉樆姝㈤潪鏂囦欢绮樿创锛堟枃瀛楃矘璐达級鐨勪簨浠跺啋娉� + e.preventDefault(); + e.stopPropagation(); + this.trigger( 'paste', allowed ); + } + }, + + destroy: function() { + this.elem.off( 'paste', this.hander ); + } + }); + }); + + /** + * @fileOverview FilePicker + */ + define('runtime/html5/filepicker',[ + 'base', + 'runtime/html5/runtime' + ], function( Base, Html5Runtime ) { + + var $ = Base.$; + + return Html5Runtime.register( 'FilePicker', { + init: function() { + var container = this.getRuntime().getContainer(), + me = this, + owner = me.owner, + opts = me.options, + lable = $( document.createElement('label') ), + input = $( document.createElement('input') ), + arr, i, len, mouseHandler; + + input.attr( 'type', 'file' ); + input.attr( 'name', opts.name ); + input.addClass('webuploader-element-invisible'); + + lable.on( 'click', function() { + input.trigger('click'); + }); + + lable.css({ + opacity: 0, + width: '100%', + height: '100%', + display: 'block', + cursor: 'pointer', + background: '#ffffff' + }); + + if ( opts.multiple ) { + input.attr( 'multiple', 'multiple' ); + } + + // @todo Firefox涓嶆敮鎸佸崟鐙寚瀹氬悗缂� + if ( opts.accept && opts.accept.length > 0 ) { + arr = []; + + for ( i = 0, len = opts.accept.length; i < len; i++ ) { + arr.push( opts.accept[ i ].mimeTypes ); + } + + input.attr( 'accept', arr.join(',') ); + } + + container.append( input ); + container.append( lable ); + + mouseHandler = function( e ) { + owner.trigger( e.type ); + }; + + input.on( 'change', function( e ) { + var fn = arguments.callee, + clone; + + me.files = e.target.files; + + // reset input + clone = this.cloneNode( true ); + this.parentNode.replaceChild( clone, this ); + + input.off(); + input = $( clone ).on( 'change', fn ) + .on( 'mouseenter mouseleave', mouseHandler ); + + owner.trigger('change'); + }); + + lable.on( 'mouseenter mouseleave', mouseHandler ); + + }, + + + getFiles: function() { + return this.files; + }, + + destroy: function() { + // todo + } + }); + }); + /** + * Terms: + * + * Uint8Array, FileReader, BlobBuilder, atob, ArrayBuffer + * @fileOverview Image鎺т欢 + */ + define('runtime/html5/util',[ + 'base' + ], function( Base ) { + + var urlAPI = window.createObjectURL && window || + window.URL && URL.revokeObjectURL && URL || + window.webkitURL, + createObjectURL = Base.noop, + revokeObjectURL = createObjectURL; + + if ( urlAPI ) { + + // 鏇村畨鍏ㄧ殑鏂瑰紡璋冪敤锛屾瘮濡俛ndroid閲岄潰灏辫兘鎶奵ontext鏀规垚鍏朵粬鐨勫璞°�� + createObjectURL = function() { + return urlAPI.createObjectURL.apply( urlAPI, arguments ); + }; + + revokeObjectURL = function() { + return urlAPI.revokeObjectURL.apply( urlAPI, arguments ); + }; + } + + return { + createObjectURL: createObjectURL, + revokeObjectURL: revokeObjectURL, + + dataURL2Blob: function( dataURI ) { + var byteStr, intArray, ab, i, mimetype, parts; + + parts = dataURI.split(','); + + if ( ~parts[ 0 ].indexOf('base64') ) { + byteStr = atob( parts[ 1 ] ); + } else { + byteStr = decodeURIComponent( parts[ 1 ] ); + } + + ab = new ArrayBuffer( byteStr.length ); + intArray = new Uint8Array( ab ); + + for ( i = 0; i < byteStr.length; i++ ) { + intArray[ i ] = byteStr.charCodeAt( i ); + } + + mimetype = parts[ 0 ].split(':')[ 1 ].split(';')[ 0 ]; + + return this.arrayBufferToBlob( ab, mimetype ); + }, + + dataURL2ArrayBuffer: function( dataURI ) { + var byteStr, intArray, i, parts; + + parts = dataURI.split(','); + + if ( ~parts[ 0 ].indexOf('base64') ) { + byteStr = atob( parts[ 1 ] ); + } else { + byteStr = decodeURIComponent( parts[ 1 ] ); + } + + intArray = new Uint8Array( byteStr.length ); + + for ( i = 0; i < byteStr.length; i++ ) { + intArray[ i ] = byteStr.charCodeAt( i ); + } + + return intArray.buffer; + }, + + arrayBufferToBlob: function( buffer, type ) { + var builder = window.BlobBuilder || window.WebKitBlobBuilder, + bb; + + // android涓嶆敮鎸佺洿鎺ew Blob, 鍙兘鍊熷姪blobbuilder. + if ( builder ) { + bb = new builder(); + bb.append( buffer ); + return bb.getBlob( type ); + } + + return new Blob([ buffer ], type ? { type: type } : {} ); + }, + + // 鎶藉嚭鏉ヤ富瑕佹槸涓轰簡瑙e喅android涓嬮潰canvas.toDataUrl涓嶆敮鎸乯peg. + // 浣犲緱鍒扮殑缁撴灉鏄痯ng. + canvasToDataUrl: function( canvas, type, quality ) { + return canvas.toDataURL( type, quality / 100 ); + }, + + // imagemeat浼氬鍐欒繖涓柟娉曪紝濡傛灉鐢ㄦ埛閫夋嫨鍔犺浇閭d釜鏂囦欢浜嗙殑璇濄�� + parseMeta: function( blob, callback ) { + callback( false, {}); + }, + + // imagemeat浼氬鍐欒繖涓柟娉曪紝濡傛灉鐢ㄦ埛閫夋嫨鍔犺浇閭d釜鏂囦欢浜嗙殑璇濄�� + updateImageHead: function( data ) { + return data; + } + }; + }); + /** + * Terms: + * + * Uint8Array, FileReader, BlobBuilder, atob, ArrayBuffer + * @fileOverview Image鎺т欢 + */ + define('runtime/html5/imagemeta',[ + 'runtime/html5/util' + ], function( Util ) { + + var api; + + api = { + parsers: { + 0xffe1: [] + }, + + maxMetaDataSize: 262144, + + parse: function( blob, cb ) { + var me = this, + fr = new FileReader(); + + fr.onload = function() { + cb( false, me._parse( this.result ) ); + fr = fr.onload = fr.onerror = null; + }; + + fr.onerror = function( e ) { + cb( e.message ); + fr = fr.onload = fr.onerror = null; + }; + + blob = blob.slice( 0, me.maxMetaDataSize ); + fr.readAsArrayBuffer( blob.getSource() ); + }, + + _parse: function( buffer, noParse ) { + if ( buffer.byteLength < 6 ) { + return; + } + + var dataview = new DataView( buffer ), + offset = 2, + maxOffset = dataview.byteLength - 4, + headLength = offset, + ret = {}, + markerBytes, markerLength, parsers, i; + + if ( dataview.getUint16( 0 ) === 0xffd8 ) { + + while ( offset < maxOffset ) { + markerBytes = dataview.getUint16( offset ); + + if ( markerBytes >= 0xffe0 && markerBytes <= 0xffef || + markerBytes === 0xfffe ) { + + markerLength = dataview.getUint16( offset + 2 ) + 2; + + if ( offset + markerLength > dataview.byteLength ) { + break; + } + + parsers = api.parsers[ markerBytes ]; + + if ( !noParse && parsers ) { + for ( i = 0; i < parsers.length; i += 1 ) { + parsers[ i ].call( api, dataview, offset, + markerLength, ret ); + } + } + + offset += markerLength; + headLength = offset; + } else { + break; + } + } + + if ( headLength > 6 ) { + if ( buffer.slice ) { + ret.imageHead = buffer.slice( 2, headLength ); + } else { + // Workaround for IE10, which does not yet + // support ArrayBuffer.slice: + ret.imageHead = new Uint8Array( buffer ) + .subarray( 2, headLength ); + } + } + } + + return ret; + }, + + updateImageHead: function( buffer, head ) { + var data = this._parse( buffer, true ), + buf1, buf2, bodyoffset; + + + bodyoffset = 2; + if ( data.imageHead ) { + bodyoffset = 2 + data.imageHead.byteLength; + } + + if ( buffer.slice ) { + buf2 = buffer.slice( bodyoffset ); + } else { + buf2 = new Uint8Array( buffer ).subarray( bodyoffset ); + } + + buf1 = new Uint8Array( head.byteLength + 2 + buf2.byteLength ); + + buf1[ 0 ] = 0xFF; + buf1[ 1 ] = 0xD8; + buf1.set( new Uint8Array( head ), 2 ); + buf1.set( new Uint8Array( buf2 ), head.byteLength + 2 ); + + return buf1.buffer; + } + }; + + Util.parseMeta = function() { + return api.parse.apply( api, arguments ); + }; + + Util.updateImageHead = function() { + return api.updateImageHead.apply( api, arguments ); + }; + + return api; + }); + /** + * 浠g爜鏉ヨ嚜浜庯細https://github.com/blueimp/JavaScript-Load-Image + * 鏆傛椂椤圭洰涓彧鐢ㄤ簡orientation. + * + * 鍘婚櫎浜� Exif Sub IFD Pointer, GPS Info IFD Pointer, Exif Thumbnail. + * @fileOverview EXIF瑙f瀽 + */ + + // Sample + // ==================================== + // Make : Apple + // Model : iPhone 4S + // Orientation : 1 + // XResolution : 72 [72/1] + // YResolution : 72 [72/1] + // ResolutionUnit : 2 + // Software : QuickTime 7.7.1 + // DateTime : 2013:09:01 22:53:55 + // ExifIFDPointer : 190 + // ExposureTime : 0.058823529411764705 [1/17] + // FNumber : 2.4 [12/5] + // ExposureProgram : Normal program + // ISOSpeedRatings : 800 + // ExifVersion : 0220 + // DateTimeOriginal : 2013:09:01 22:52:51 + // DateTimeDigitized : 2013:09:01 22:52:51 + // ComponentsConfiguration : YCbCr + // ShutterSpeedValue : 4.058893515764426 + // ApertureValue : 2.5260688216892597 [4845/1918] + // BrightnessValue : -0.3126686601998395 + // MeteringMode : Pattern + // Flash : Flash did not fire, compulsory flash mode + // FocalLength : 4.28 [107/25] + // SubjectArea : [4 values] + // FlashpixVersion : 0100 + // ColorSpace : 1 + // PixelXDimension : 2448 + // PixelYDimension : 3264 + // SensingMethod : One-chip color area sensor + // ExposureMode : 0 + // WhiteBalance : Auto white balance + // FocalLengthIn35mmFilm : 35 + // SceneCaptureType : Standard + define('runtime/html5/imagemeta/exif',[ + 'base', + 'runtime/html5/imagemeta' + ], function( Base, ImageMeta ) { + + var EXIF = {}; + + EXIF.ExifMap = function() { + return this; + }; + + EXIF.ExifMap.prototype.map = { + 'Orientation': 0x0112 + }; + + EXIF.ExifMap.prototype.get = function( id ) { + return this[ id ] || this[ this.map[ id ] ]; + }; + + EXIF.exifTagTypes = { + // byte, 8-bit unsigned int: + 1: { + getValue: function( dataView, dataOffset ) { + return dataView.getUint8( dataOffset ); + }, + size: 1 + }, + + // ascii, 8-bit byte: + 2: { + getValue: function( dataView, dataOffset ) { + return String.fromCharCode( dataView.getUint8( dataOffset ) ); + }, + size: 1, + ascii: true + }, + + // short, 16 bit int: + 3: { + getValue: function( dataView, dataOffset, littleEndian ) { + return dataView.getUint16( dataOffset, littleEndian ); + }, + size: 2 + }, + + // long, 32 bit int: + 4: { + getValue: function( dataView, dataOffset, littleEndian ) { + return dataView.getUint32( dataOffset, littleEndian ); + }, + size: 4 + }, + + // rational = two long values, + // first is numerator, second is denominator: + 5: { + getValue: function( dataView, dataOffset, littleEndian ) { + return dataView.getUint32( dataOffset, littleEndian ) / + dataView.getUint32( dataOffset + 4, littleEndian ); + }, + size: 8 + }, + + // slong, 32 bit signed int: + 9: { + getValue: function( dataView, dataOffset, littleEndian ) { + return dataView.getInt32( dataOffset, littleEndian ); + }, + size: 4 + }, + + // srational, two slongs, first is numerator, second is denominator: + 10: { + getValue: function( dataView, dataOffset, littleEndian ) { + return dataView.getInt32( dataOffset, littleEndian ) / + dataView.getInt32( dataOffset + 4, littleEndian ); + }, + size: 8 + } + }; + + // undefined, 8-bit byte, value depending on field: + EXIF.exifTagTypes[ 7 ] = EXIF.exifTagTypes[ 1 ]; + + EXIF.getExifValue = function( dataView, tiffOffset, offset, type, length, + littleEndian ) { + + var tagType = EXIF.exifTagTypes[ type ], + tagSize, dataOffset, values, i, str, c; + + if ( !tagType ) { + Base.log('Invalid Exif data: Invalid tag type.'); + return; + } + + tagSize = tagType.size * length; + + // Determine if the value is contained in the dataOffset bytes, + // or if the value at the dataOffset is a pointer to the actual data: + dataOffset = tagSize > 4 ? tiffOffset + dataView.getUint32( offset + 8, + littleEndian ) : (offset + 8); + + if ( dataOffset + tagSize > dataView.byteLength ) { + Base.log('Invalid Exif data: Invalid data offset.'); + return; + } + + if ( length === 1 ) { + return tagType.getValue( dataView, dataOffset, littleEndian ); + } + + values = []; + + for ( i = 0; i < length; i += 1 ) { + values[ i ] = tagType.getValue( dataView, + dataOffset + i * tagType.size, littleEndian ); + } + + if ( tagType.ascii ) { + str = ''; + + // Concatenate the chars: + for ( i = 0; i < values.length; i += 1 ) { + c = values[ i ]; + + // Ignore the terminating NULL byte(s): + if ( c === '\u0000' ) { + break; + } + str += c; + } + + return str; + } + return values; + }; + + EXIF.parseExifTag = function( dataView, tiffOffset, offset, littleEndian, + data ) { + + var tag = dataView.getUint16( offset, littleEndian ); + data.exif[ tag ] = EXIF.getExifValue( dataView, tiffOffset, offset, + dataView.getUint16( offset + 2, littleEndian ), // tag type + dataView.getUint32( offset + 4, littleEndian ), // tag length + littleEndian ); + }; + + EXIF.parseExifTags = function( dataView, tiffOffset, dirOffset, + littleEndian, data ) { + + var tagsNumber, dirEndOffset, i; + + if ( dirOffset + 6 > dataView.byteLength ) { + Base.log('Invalid Exif data: Invalid directory offset.'); + return; + } + + tagsNumber = dataView.getUint16( dirOffset, littleEndian ); + dirEndOffset = dirOffset + 2 + 12 * tagsNumber; + + if ( dirEndOffset + 4 > dataView.byteLength ) { + Base.log('Invalid Exif data: Invalid directory size.'); + return; + } + + for ( i = 0; i < tagsNumber; i += 1 ) { + this.parseExifTag( dataView, tiffOffset, + dirOffset + 2 + 12 * i, // tag offset + littleEndian, data ); + } + + // Return the offset to the next directory: + return dataView.getUint32( dirEndOffset, littleEndian ); + }; + + // EXIF.getExifThumbnail = function(dataView, offset, length) { + // var hexData, + // i, + // b; + // if (!length || offset + length > dataView.byteLength) { + // Base.log('Invalid Exif data: Invalid thumbnail data.'); + // return; + // } + // hexData = []; + // for (i = 0; i < length; i += 1) { + // b = dataView.getUint8(offset + i); + // hexData.push((b < 16 ? '0' : '') + b.toString(16)); + // } + // return 'data:image/jpeg,%' + hexData.join('%'); + // }; + + EXIF.parseExifData = function( dataView, offset, length, data ) { + + var tiffOffset = offset + 10, + littleEndian, dirOffset; + + // Check for the ASCII code for "Exif" (0x45786966): + if ( dataView.getUint32( offset + 4 ) !== 0x45786966 ) { + // No Exif data, might be XMP data instead + return; + } + if ( tiffOffset + 8 > dataView.byteLength ) { + Base.log('Invalid Exif data: Invalid segment size.'); + return; + } + + // Check for the two null bytes: + if ( dataView.getUint16( offset + 8 ) !== 0x0000 ) { + Base.log('Invalid Exif data: Missing byte alignment offset.'); + return; + } + + // Check the byte alignment: + switch ( dataView.getUint16( tiffOffset ) ) { + case 0x4949: + littleEndian = true; + break; + + case 0x4D4D: + littleEndian = false; + break; + + default: + Base.log('Invalid Exif data: Invalid byte alignment marker.'); + return; + } + + // Check for the TIFF tag marker (0x002A): + if ( dataView.getUint16( tiffOffset + 2, littleEndian ) !== 0x002A ) { + Base.log('Invalid Exif data: Missing TIFF marker.'); + return; + } + + // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal: + dirOffset = dataView.getUint32( tiffOffset + 4, littleEndian ); + // Create the exif object to store the tags: + data.exif = new EXIF.ExifMap(); + // Parse the tags of the main image directory and retrieve the + // offset to the next directory, usually the thumbnail directory: + dirOffset = EXIF.parseExifTags( dataView, tiffOffset, + tiffOffset + dirOffset, littleEndian, data ); + + // 灏濊瘯璇诲彇缂╃暐鍥� + // if ( dirOffset ) { + // thumbnailData = {exif: {}}; + // dirOffset = EXIF.parseExifTags( + // dataView, + // tiffOffset, + // tiffOffset + dirOffset, + // littleEndian, + // thumbnailData + // ); + + // // Check for JPEG Thumbnail offset: + // if (thumbnailData.exif[0x0201]) { + // data.exif.Thumbnail = EXIF.getExifThumbnail( + // dataView, + // tiffOffset + thumbnailData.exif[0x0201], + // thumbnailData.exif[0x0202] // Thumbnail data length + // ); + // } + // } + }; + + ImageMeta.parsers[ 0xffe1 ].push( EXIF.parseExifData ); + return EXIF; + }); + /** + * 杩欎釜鏂瑰紡鎬ц兘涓嶈锛屼絾鏄彲浠ヨВ鍐砤ndroid閲岄潰鐨則oDataUrl鐨刡ug + * android閲岄潰toDataUrl('image/jpege')寰楀埌鐨勭粨鏋滃嵈鏄痯ng. + * + * 鎵�浠ヨ繖閲屾病杈欙紝鍙兘鍊熷姪杩欎釜宸ュ叿 + * @fileOverview jpeg encoder + */ + define('runtime/html5/jpegencoder',[], function( require, exports, module ) { + + /* + Copyright (c) 2008, Adobe Systems Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Adobe Systems Incorporated nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + /* + JPEG encoder ported to JavaScript and optimized by Andreas Ritter, www.bytestrom.eu, 11/2009 + + Basic GUI blocking jpeg encoder + */ + + function JPEGEncoder(quality) { + var self = this; + var fround = Math.round; + var ffloor = Math.floor; + var YTable = new Array(64); + var UVTable = new Array(64); + var fdtbl_Y = new Array(64); + var fdtbl_UV = new Array(64); + var YDC_HT; + var UVDC_HT; + var YAC_HT; + var UVAC_HT; + + var bitcode = new Array(65535); + var category = new Array(65535); + var outputfDCTQuant = new Array(64); + var DU = new Array(64); + var byteout = []; + var bytenew = 0; + var bytepos = 7; + + var YDU = new Array(64); + var UDU = new Array(64); + var VDU = new Array(64); + var clt = new Array(256); + var RGB_YUV_TABLE = new Array(2048); + var currentQuality; + + var ZigZag = [ + 0, 1, 5, 6,14,15,27,28, + 2, 4, 7,13,16,26,29,42, + 3, 8,12,17,25,30,41,43, + 9,11,18,24,31,40,44,53, + 10,19,23,32,39,45,52,54, + 20,22,33,38,46,51,55,60, + 21,34,37,47,50,56,59,61, + 35,36,48,49,57,58,62,63 + ]; + + var std_dc_luminance_nrcodes = [0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0]; + var std_dc_luminance_values = [0,1,2,3,4,5,6,7,8,9,10,11]; + var std_ac_luminance_nrcodes = [0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d]; + var std_ac_luminance_values = [ + 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12, + 0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07, + 0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08, + 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0, + 0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16, + 0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28, + 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39, + 0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49, + 0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59, + 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69, + 0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79, + 0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89, + 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98, + 0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7, + 0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6, + 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5, + 0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4, + 0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2, + 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea, + 0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8, + 0xf9,0xfa + ]; + + var std_dc_chrominance_nrcodes = [0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0]; + var std_dc_chrominance_values = [0,1,2,3,4,5,6,7,8,9,10,11]; + var std_ac_chrominance_nrcodes = [0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77]; + var std_ac_chrominance_values = [ + 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21, + 0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71, + 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91, + 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0, + 0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34, + 0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26, + 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38, + 0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48, + 0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58, + 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68, + 0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78, + 0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87, + 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96, + 0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5, + 0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4, + 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3, + 0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2, + 0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda, + 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9, + 0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8, + 0xf9,0xfa + ]; + + function initQuantTables(sf){ + var YQT = [ + 16, 11, 10, 16, 24, 40, 51, 61, + 12, 12, 14, 19, 26, 58, 60, 55, + 14, 13, 16, 24, 40, 57, 69, 56, + 14, 17, 22, 29, 51, 87, 80, 62, + 18, 22, 37, 56, 68,109,103, 77, + 24, 35, 55, 64, 81,104,113, 92, + 49, 64, 78, 87,103,121,120,101, + 72, 92, 95, 98,112,100,103, 99 + ]; + + for (var i = 0; i < 64; i++) { + var t = ffloor((YQT[i]*sf+50)/100); + if (t < 1) { + t = 1; + } else if (t > 255) { + t = 255; + } + YTable[ZigZag[i]] = t; + } + var UVQT = [ + 17, 18, 24, 47, 99, 99, 99, 99, + 18, 21, 26, 66, 99, 99, 99, 99, + 24, 26, 56, 99, 99, 99, 99, 99, + 47, 66, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 + ]; + for (var j = 0; j < 64; j++) { + var u = ffloor((UVQT[j]*sf+50)/100); + if (u < 1) { + u = 1; + } else if (u > 255) { + u = 255; + } + UVTable[ZigZag[j]] = u; + } + var aasf = [ + 1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379 + ]; + var k = 0; + for (var row = 0; row < 8; row++) + { + for (var col = 0; col < 8; col++) + { + fdtbl_Y[k] = (1.0 / (YTable [ZigZag[k]] * aasf[row] * aasf[col] * 8.0)); + fdtbl_UV[k] = (1.0 / (UVTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0)); + k++; + } + } + } + + function computeHuffmanTbl(nrcodes, std_table){ + var codevalue = 0; + var pos_in_table = 0; + var HT = new Array(); + for (var k = 1; k <= 16; k++) { + for (var j = 1; j <= nrcodes[k]; j++) { + HT[std_table[pos_in_table]] = []; + HT[std_table[pos_in_table]][0] = codevalue; + HT[std_table[pos_in_table]][1] = k; + pos_in_table++; + codevalue++; + } + codevalue*=2; + } + return HT; + } + + function initHuffmanTbl() + { + YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes,std_dc_luminance_values); + UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes,std_dc_chrominance_values); + YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes,std_ac_luminance_values); + UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes,std_ac_chrominance_values); + } + + function initCategoryNumber() + { + var nrlower = 1; + var nrupper = 2; + for (var cat = 1; cat <= 15; cat++) { + //Positive numbers + for (var nr = nrlower; nr<nrupper; nr++) { + category[32767+nr] = cat; + bitcode[32767+nr] = []; + bitcode[32767+nr][1] = cat; + bitcode[32767+nr][0] = nr; + } + //Negative numbers + for (var nrneg =-(nrupper-1); nrneg<=-nrlower; nrneg++) { + category[32767+nrneg] = cat; + bitcode[32767+nrneg] = []; + bitcode[32767+nrneg][1] = cat; + bitcode[32767+nrneg][0] = nrupper-1+nrneg; + } + nrlower <<= 1; + nrupper <<= 1; + } + } + + function initRGBYUVTable() { + for(var i = 0; i < 256;i++) { + RGB_YUV_TABLE[i] = 19595 * i; + RGB_YUV_TABLE[(i+ 256)>>0] = 38470 * i; + RGB_YUV_TABLE[(i+ 512)>>0] = 7471 * i + 0x8000; + RGB_YUV_TABLE[(i+ 768)>>0] = -11059 * i; + RGB_YUV_TABLE[(i+1024)>>0] = -21709 * i; + RGB_YUV_TABLE[(i+1280)>>0] = 32768 * i + 0x807FFF; + RGB_YUV_TABLE[(i+1536)>>0] = -27439 * i; + RGB_YUV_TABLE[(i+1792)>>0] = - 5329 * i; + } + } + + // IO functions + function writeBits(bs) + { + var value = bs[0]; + var posval = bs[1]-1; + while ( posval >= 0 ) { + if (value & (1 << posval) ) { + bytenew |= (1 << bytepos); + } + posval--; + bytepos--; + if (bytepos < 0) { + if (bytenew == 0xFF) { + writeByte(0xFF); + writeByte(0); + } + else { + writeByte(bytenew); + } + bytepos=7; + bytenew=0; + } + } + } + + function writeByte(value) + { + byteout.push(clt[value]); // write char directly instead of converting later + } + + function writeWord(value) + { + writeByte((value>>8)&0xFF); + writeByte((value )&0xFF); + } + + // DCT & quantization core + function fDCTQuant(data, fdtbl) + { + var d0, d1, d2, d3, d4, d5, d6, d7; + /* Pass 1: process rows. */ + var dataOff=0; + var i; + var I8 = 8; + var I64 = 64; + for (i=0; i<I8; ++i) + { + d0 = data[dataOff]; + d1 = data[dataOff+1]; + d2 = data[dataOff+2]; + d3 = data[dataOff+3]; + d4 = data[dataOff+4]; + d5 = data[dataOff+5]; + d6 = data[dataOff+6]; + d7 = data[dataOff+7]; + + var tmp0 = d0 + d7; + var tmp7 = d0 - d7; + var tmp1 = d1 + d6; + var tmp6 = d1 - d6; + var tmp2 = d2 + d5; + var tmp5 = d2 - d5; + var tmp3 = d3 + d4; + var tmp4 = d3 - d4; + + /* Even part */ + var tmp10 = tmp0 + tmp3; /* phase 2 */ + var tmp13 = tmp0 - tmp3; + var tmp11 = tmp1 + tmp2; + var tmp12 = tmp1 - tmp2; + + data[dataOff] = tmp10 + tmp11; /* phase 3 */ + data[dataOff+4] = tmp10 - tmp11; + + var z1 = (tmp12 + tmp13) * 0.707106781; /* c4 */ + data[dataOff+2] = tmp13 + z1; /* phase 5 */ + data[dataOff+6] = tmp13 - z1; + + /* Odd part */ + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + var z5 = (tmp10 - tmp12) * 0.382683433; /* c6 */ + var z2 = 0.541196100 * tmp10 + z5; /* c2-c6 */ + var z4 = 1.306562965 * tmp12 + z5; /* c2+c6 */ + var z3 = tmp11 * 0.707106781; /* c4 */ + + var z11 = tmp7 + z3; /* phase 5 */ + var z13 = tmp7 - z3; + + data[dataOff+5] = z13 + z2; /* phase 6 */ + data[dataOff+3] = z13 - z2; + data[dataOff+1] = z11 + z4; + data[dataOff+7] = z11 - z4; + + dataOff += 8; /* advance pointer to next row */ + } + + /* Pass 2: process columns. */ + dataOff = 0; + for (i=0; i<I8; ++i) + { + d0 = data[dataOff]; + d1 = data[dataOff + 8]; + d2 = data[dataOff + 16]; + d3 = data[dataOff + 24]; + d4 = data[dataOff + 32]; + d5 = data[dataOff + 40]; + d6 = data[dataOff + 48]; + d7 = data[dataOff + 56]; + + var tmp0p2 = d0 + d7; + var tmp7p2 = d0 - d7; + var tmp1p2 = d1 + d6; + var tmp6p2 = d1 - d6; + var tmp2p2 = d2 + d5; + var tmp5p2 = d2 - d5; + var tmp3p2 = d3 + d4; + var tmp4p2 = d3 - d4; + + /* Even part */ + var tmp10p2 = tmp0p2 + tmp3p2; /* phase 2 */ + var tmp13p2 = tmp0p2 - tmp3p2; + var tmp11p2 = tmp1p2 + tmp2p2; + var tmp12p2 = tmp1p2 - tmp2p2; + + data[dataOff] = tmp10p2 + tmp11p2; /* phase 3 */ + data[dataOff+32] = tmp10p2 - tmp11p2; + + var z1p2 = (tmp12p2 + tmp13p2) * 0.707106781; /* c4 */ + data[dataOff+16] = tmp13p2 + z1p2; /* phase 5 */ + data[dataOff+48] = tmp13p2 - z1p2; + + /* Odd part */ + tmp10p2 = tmp4p2 + tmp5p2; /* phase 2 */ + tmp11p2 = tmp5p2 + tmp6p2; + tmp12p2 = tmp6p2 + tmp7p2; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + var z5p2 = (tmp10p2 - tmp12p2) * 0.382683433; /* c6 */ + var z2p2 = 0.541196100 * tmp10p2 + z5p2; /* c2-c6 */ + var z4p2 = 1.306562965 * tmp12p2 + z5p2; /* c2+c6 */ + var z3p2 = tmp11p2 * 0.707106781; /* c4 */ + + var z11p2 = tmp7p2 + z3p2; /* phase 5 */ + var z13p2 = tmp7p2 - z3p2; + + data[dataOff+40] = z13p2 + z2p2; /* phase 6 */ + data[dataOff+24] = z13p2 - z2p2; + data[dataOff+ 8] = z11p2 + z4p2; + data[dataOff+56] = z11p2 - z4p2; + + dataOff++; /* advance pointer to next column */ + } + + // Quantize/descale the coefficients + var fDCTQuant; + for (i=0; i<I64; ++i) + { + // Apply the quantization and scaling factor & Round to nearest integer + fDCTQuant = data[i]*fdtbl[i]; + outputfDCTQuant[i] = (fDCTQuant > 0.0) ? ((fDCTQuant + 0.5)|0) : ((fDCTQuant - 0.5)|0); + //outputfDCTQuant[i] = fround(fDCTQuant); + + } + return outputfDCTQuant; + } + + function writeAPP0() + { + writeWord(0xFFE0); // marker + writeWord(16); // length + writeByte(0x4A); // J + writeByte(0x46); // F + writeByte(0x49); // I + writeByte(0x46); // F + writeByte(0); // = "JFIF",'\0' + writeByte(1); // versionhi + writeByte(1); // versionlo + writeByte(0); // xyunits + writeWord(1); // xdensity + writeWord(1); // ydensity + writeByte(0); // thumbnwidth + writeByte(0); // thumbnheight + } + + function writeSOF0(width, height) + { + writeWord(0xFFC0); // marker + writeWord(17); // length, truecolor YUV JPG + writeByte(8); // precision + writeWord(height); + writeWord(width); + writeByte(3); // nrofcomponents + writeByte(1); // IdY + writeByte(0x11); // HVY + writeByte(0); // QTY + writeByte(2); // IdU + writeByte(0x11); // HVU + writeByte(1); // QTU + writeByte(3); // IdV + writeByte(0x11); // HVV + writeByte(1); // QTV + } + + function writeDQT() + { + writeWord(0xFFDB); // marker + writeWord(132); // length + writeByte(0); + for (var i=0; i<64; i++) { + writeByte(YTable[i]); + } + writeByte(1); + for (var j=0; j<64; j++) { + writeByte(UVTable[j]); + } + } + + function writeDHT() + { + writeWord(0xFFC4); // marker + writeWord(0x01A2); // length + + writeByte(0); // HTYDCinfo + for (var i=0; i<16; i++) { + writeByte(std_dc_luminance_nrcodes[i+1]); + } + for (var j=0; j<=11; j++) { + writeByte(std_dc_luminance_values[j]); + } + + writeByte(0x10); // HTYACinfo + for (var k=0; k<16; k++) { + writeByte(std_ac_luminance_nrcodes[k+1]); + } + for (var l=0; l<=161; l++) { + writeByte(std_ac_luminance_values[l]); + } + + writeByte(1); // HTUDCinfo + for (var m=0; m<16; m++) { + writeByte(std_dc_chrominance_nrcodes[m+1]); + } + for (var n=0; n<=11; n++) { + writeByte(std_dc_chrominance_values[n]); + } + + writeByte(0x11); // HTUACinfo + for (var o=0; o<16; o++) { + writeByte(std_ac_chrominance_nrcodes[o+1]); + } + for (var p=0; p<=161; p++) { + writeByte(std_ac_chrominance_values[p]); + } + } + + function writeSOS() + { + writeWord(0xFFDA); // marker + writeWord(12); // length + writeByte(3); // nrofcomponents + writeByte(1); // IdY + writeByte(0); // HTY + writeByte(2); // IdU + writeByte(0x11); // HTU + writeByte(3); // IdV + writeByte(0x11); // HTV + writeByte(0); // Ss + writeByte(0x3f); // Se + writeByte(0); // Bf + } + + function processDU(CDU, fdtbl, DC, HTDC, HTAC){ + var EOB = HTAC[0x00]; + var M16zeroes = HTAC[0xF0]; + var pos; + var I16 = 16; + var I63 = 63; + var I64 = 64; + var DU_DCT = fDCTQuant(CDU, fdtbl); + //ZigZag reorder + for (var j=0;j<I64;++j) { + DU[ZigZag[j]]=DU_DCT[j]; + } + var Diff = DU[0] - DC; DC = DU[0]; + //Encode DC + if (Diff==0) { + writeBits(HTDC[0]); // Diff might be 0 + } else { + pos = 32767+Diff; + writeBits(HTDC[category[pos]]); + writeBits(bitcode[pos]); + } + //Encode ACs + var end0pos = 63; // was const... which is crazy + for (; (end0pos>0)&&(DU[end0pos]==0); end0pos--) {}; + //end0pos = first element in reverse order !=0 + if ( end0pos == 0) { + writeBits(EOB); + return DC; + } + var i = 1; + var lng; + while ( i <= end0pos ) { + var startpos = i; + for (; (DU[i]==0) && (i<=end0pos); ++i) {} + var nrzeroes = i-startpos; + if ( nrzeroes >= I16 ) { + lng = nrzeroes>>4; + for (var nrmarker=1; nrmarker <= lng; ++nrmarker) + writeBits(M16zeroes); + nrzeroes = nrzeroes&0xF; + } + pos = 32767+DU[i]; + writeBits(HTAC[(nrzeroes<<4)+category[pos]]); + writeBits(bitcode[pos]); + i++; + } + if ( end0pos != I63 ) { + writeBits(EOB); + } + return DC; + } + + function initCharLookupTable(){ + var sfcc = String.fromCharCode; + for(var i=0; i < 256; i++){ ///// ACHTUNG // 255 + clt[i] = sfcc(i); + } + } + + this.encode = function(image,quality) // image data object + { + // var time_start = new Date().getTime(); + + if(quality) setQuality(quality); + + // Initialize bit writer + byteout = new Array(); + bytenew=0; + bytepos=7; + + // Add JPEG headers + writeWord(0xFFD8); // SOI + writeAPP0(); + writeDQT(); + writeSOF0(image.width,image.height); + writeDHT(); + writeSOS(); + + + // Encode 8x8 macroblocks + var DCY=0; + var DCU=0; + var DCV=0; + + bytenew=0; + bytepos=7; + + + this.encode.displayName = "_encode_"; + + var imageData = image.data; + var width = image.width; + var height = image.height; + + var quadWidth = width*4; + var tripleWidth = width*3; + + var x, y = 0; + var r, g, b; + var start,p, col,row,pos; + while(y < height){ + x = 0; + while(x < quadWidth){ + start = quadWidth * y + x; + p = start; + col = -1; + row = 0; + + for(pos=0; pos < 64; pos++){ + row = pos >> 3;// /8 + col = ( pos & 7 ) * 4; // %8 + p = start + ( row * quadWidth ) + col; + + if(y+row >= height){ // padding bottom + p-= (quadWidth*(y+1+row-height)); + } + + if(x+col >= quadWidth){ // padding right + p-= ((x+col) - quadWidth +4) + } + + r = imageData[ p++ ]; + g = imageData[ p++ ]; + b = imageData[ p++ ]; + + + /* // calculate YUV values dynamically + YDU[pos]=((( 0.29900)*r+( 0.58700)*g+( 0.11400)*b))-128; //-0x80 + UDU[pos]=(((-0.16874)*r+(-0.33126)*g+( 0.50000)*b)); + VDU[pos]=((( 0.50000)*r+(-0.41869)*g+(-0.08131)*b)); + */ + + // use lookup table (slightly faster) + YDU[pos] = ((RGB_YUV_TABLE[r] + RGB_YUV_TABLE[(g + 256)>>0] + RGB_YUV_TABLE[(b + 512)>>0]) >> 16)-128; + UDU[pos] = ((RGB_YUV_TABLE[(r + 768)>>0] + RGB_YUV_TABLE[(g + 1024)>>0] + RGB_YUV_TABLE[(b + 1280)>>0]) >> 16)-128; + VDU[pos] = ((RGB_YUV_TABLE[(r + 1280)>>0] + RGB_YUV_TABLE[(g + 1536)>>0] + RGB_YUV_TABLE[(b + 1792)>>0]) >> 16)-128; + + } + + DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); + DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); + x+=32; + } + y+=8; + } + + + //////////////////////////////////////////////////////////////// + + // Do the bit alignment of the EOI marker + if ( bytepos >= 0 ) { + var fillbits = []; + fillbits[1] = bytepos+1; + fillbits[0] = (1<<(bytepos+1))-1; + writeBits(fillbits); + } + + writeWord(0xFFD9); //EOI + + var jpegDataUri = 'data:image/jpeg;base64,' + btoa(byteout.join('')); + + byteout = []; + + // benchmarking + // var duration = new Date().getTime() - time_start; + // console.log('Encoding time: '+ currentQuality + 'ms'); + // + + return jpegDataUri + } + + function setQuality(quality){ + if (quality <= 0) { + quality = 1; + } + if (quality > 100) { + quality = 100; + } + + if(currentQuality == quality) return // don't recalc if unchanged + + var sf = 0; + if (quality < 50) { + sf = Math.floor(5000 / quality); + } else { + sf = Math.floor(200 - quality*2); + } + + initQuantTables(sf); + currentQuality = quality; + // console.log('Quality set to: '+quality +'%'); + } + + function init(){ + // var time_start = new Date().getTime(); + if(!quality) quality = 50; + // Create tables + initCharLookupTable() + initHuffmanTbl(); + initCategoryNumber(); + initRGBYUVTable(); + + setQuality(quality); + // var duration = new Date().getTime() - time_start; + // console.log('Initialization '+ duration + 'ms'); + } + + init(); + + }; + + JPEGEncoder.encode = function( data, quality ) { + var encoder = new JPEGEncoder( quality ); + + return encoder.encode( data ); + } + + return JPEGEncoder; + }); + /** + * @fileOverview Fix android canvas.toDataUrl bug. + */ + define('runtime/html5/androidpatch',[ + 'runtime/html5/util', + 'runtime/html5/jpegencoder', + 'base' + ], function( Util, encoder, Base ) { + var origin = Util.canvasToDataUrl, + supportJpeg; + + Util.canvasToDataUrl = function( canvas, type, quality ) { + var ctx, w, h, fragement, parts; + + // 闈瀉ndroid鎵嬫満鐩存帴璺宠繃銆� + if ( !Base.os.android ) { + return origin.apply( null, arguments ); + } + + // 妫�娴嬫槸鍚anvas鏀寔jpeg瀵煎嚭锛屾牴鎹暟鎹牸寮忔潵鍒ゆ柇銆� + // JPEG 鍓嶄袱浣嶅垎鍒槸锛�255, 216 + if ( type === 'image/jpeg' && typeof supportJpeg === 'undefined' ) { + fragement = origin.apply( null, arguments ); + + parts = fragement.split(','); + + if ( ~parts[ 0 ].indexOf('base64') ) { + fragement = atob( parts[ 1 ] ); + } else { + fragement = decodeURIComponent( parts[ 1 ] ); + } + + fragement = fragement.substring( 0, 2 ); + + supportJpeg = fragement.charCodeAt( 0 ) === 255 && + fragement.charCodeAt( 1 ) === 216; + } + + // 鍙湁鍦╝ndroid鐜涓嬫墠淇 + if ( type === 'image/jpeg' && !supportJpeg ) { + w = canvas.width; + h = canvas.height; + ctx = canvas.getContext('2d'); + + return encoder.encode( ctx.getImageData( 0, 0, w, h ), quality ); + } + + return origin.apply( null, arguments ); + }; + }); + /** + * @fileOverview Image + */ + define('runtime/html5/image',[ + 'base', + 'runtime/html5/runtime', + 'runtime/html5/util' + ], function( Base, Html5Runtime, Util ) { + + var BLANK = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D'; + + return Html5Runtime.register( 'Image', { + + // flag: 鏍囪鏄惁琚慨鏀硅繃銆� + modified: false, + + init: function() { + var me = this, + img = new Image(); + + img.onload = function() { + + me._info = { + type: me.type, + width: this.width, + height: this.height + }; + + // 璇诲彇meta淇℃伅銆� + if ( !me._metas && 'image/jpeg' === me.type ) { + Util.parseMeta( me._blob, function( error, ret ) { + me._metas = ret; + me.owner.trigger('load'); + }); + } else { + me.owner.trigger('load'); + } + }; + + img.onerror = function() { + me.owner.trigger('error'); + }; + + me._img = img; + }, + + loadFromBlob: function( blob ) { + var me = this, + img = me._img; + + me._blob = blob; + me.type = blob.type; + img.src = Util.createObjectURL( blob.getSource() ); + me.owner.once( 'load', function() { + Util.revokeObjectURL( img.src ); + }); + }, + + resize: function( width, height ) { + var canvas = this._canvas || + (this._canvas = document.createElement('canvas')); + + this._resize( this._img, canvas, width, height ); + this._blob = null; // 娌$敤浜嗭紝鍙互鍒犳帀浜嗐�� + this.modified = true; + this.owner.trigger('complete'); + }, + + getAsBlob: function( type ) { + var blob = this._blob, + opts = this.options, + canvas; + + type = type || this.type; + + // blob闇�瑕侀噸鏂扮敓鎴愩�� + if ( this.modified || this.type !== type ) { + canvas = this._canvas; + + if ( type === 'image/jpeg' ) { + + blob = Util.canvasToDataUrl( canvas, 'image/jpeg', + opts.quality ); + + if ( opts.preserveHeaders && this._metas && + this._metas.imageHead ) { + + blob = Util.dataURL2ArrayBuffer( blob ); + blob = Util.updateImageHead( blob, + this._metas.imageHead ); + blob = Util.arrayBufferToBlob( blob, type ); + return blob; + } + } else { + blob = Util.canvasToDataUrl( canvas, type ); + } + + blob = Util.dataURL2Blob( blob ); + } + + return blob; + }, + + getAsDataUrl: function( type ) { + var opts = this.options; + + type = type || this.type; + + if ( type === 'image/jpeg' ) { + return Util.canvasToDataUrl( this._canvas, type, opts.quality ); + } else { + return this._canvas.toDataURL( type ); + } + }, + + getOrientation: function() { + return this._metas && this._metas.exif && + this._metas.exif.get('Orientation') || 1; + }, + + info: function( val ) { + + // setter + if ( val ) { + this._info = val; + return this; + } + + // getter + return this._info; + }, + + meta: function( val ) { + + // setter + if ( val ) { + this._meta = val; + return this; + } + + // getter + return this._meta; + }, + + destroy: function() { + var canvas = this._canvas; + this._img.onload = null; + + if ( canvas ) { + canvas.getContext('2d') + .clearRect( 0, 0, canvas.width, canvas.height ); + canvas.width = canvas.height = 0; + this._canvas = null; + } + + // 閲婃斁鍐呭瓨銆傞潪甯搁噸瑕侊紝鍚﹀垯閲婃斁涓嶄簡image鐨勫唴瀛樸�� + this._img.src = BLANK; + this._img = this._blob = null; + }, + + _resize: function( img, cvs, width, height ) { + var opts = this.options, + naturalWidth = img.width, + naturalHeight = img.height, + orientation = this.getOrientation(), + scale, w, h, x, y; + + // values that require 90 degree rotation + if ( ~[ 5, 6, 7, 8 ].indexOf( orientation ) ) { + + // 浜ゆ崲width, height鐨勫�笺�� + width ^= height; + height ^= width; + width ^= height; + } + + scale = Math[ opts.crop ? 'max' : 'min' ]( width / naturalWidth, + height / naturalHeight ); + + // 涓嶅厑璁告斁澶с�� + opts.allowMagnify || (scale = Math.min( 1, scale )); + + w = naturalWidth * scale; + h = naturalHeight * scale; + + if ( opts.crop ) { + cvs.width = width; + cvs.height = height; + } else { + cvs.width = w; + cvs.height = h; + } + + x = (cvs.width - w) / 2; + y = (cvs.height - h) / 2; + + opts.preserveHeaders || this._rotate2Orientaion( cvs, orientation ); + + this._renderImageToCanvas( cvs, img, x, y, w, h ); + }, + + _rotate2Orientaion: function( canvas, orientation ) { + var width = canvas.width, + height = canvas.height, + ctx = canvas.getContext('2d'); + + switch ( orientation ) { + case 5: + case 6: + case 7: + case 8: + canvas.width = height; + canvas.height = width; + break; + } + + switch ( orientation ) { + case 2: // horizontal flip + ctx.translate( width, 0 ); + ctx.scale( -1, 1 ); + break; + + case 3: // 180 rotate left + ctx.translate( width, height ); + ctx.rotate( Math.PI ); + break; + + case 4: // vertical flip + ctx.translate( 0, height ); + ctx.scale( 1, -1 ); + break; + + case 5: // vertical flip + 90 rotate right + ctx.rotate( 0.5 * Math.PI ); + ctx.scale( 1, -1 ); + break; + + case 6: // 90 rotate right + ctx.rotate( 0.5 * Math.PI ); + ctx.translate( 0, -height ); + break; + + case 7: // horizontal flip + 90 rotate right + ctx.rotate( 0.5 * Math.PI ); + ctx.translate( width, -height ); + ctx.scale( -1, 1 ); + break; + + case 8: // 90 rotate left + ctx.rotate( -0.5 * Math.PI ); + ctx.translate( -width, 0 ); + break; + } + }, + + // https://github.com/stomita/ios-imagefile-megapixel/ + // blob/master/src/megapix-image.js + _renderImageToCanvas: (function() { + + // 濡傛灉涓嶆槸ios, 涓嶉渶瑕佽繖涔堝鏉傦紒 + if ( !Base.os.ios ) { + return function( canvas, img, x, y, w, h ) { + canvas.getContext('2d').drawImage( img, x, y, w, h ); + }; + } + + /** + * Detecting vertical squash in loaded image. + * Fixes a bug which squash image vertically while drawing into + * canvas for some images. + */ + function detectVerticalSquash( img, iw, ih ) { + var canvas = document.createElement('canvas'), + ctx = canvas.getContext('2d'), + sy = 0, + ey = ih, + py = ih, + data, alpha, ratio; + + + canvas.width = 1; + canvas.height = ih; + ctx.drawImage( img, 0, 0 ); + data = ctx.getImageData( 0, 0, 1, ih ).data; + + // search image edge pixel position in case + // it is squashed vertically. + while ( py > sy ) { + alpha = data[ (py - 1) * 4 + 3 ]; + + if ( alpha === 0 ) { + ey = py; + } else { + sy = py; + } + + py = (ey + sy) >> 1; + } + + ratio = (py / ih); + return (ratio === 0) ? 1 : ratio; + } + + // fix ie7 bug + // http://stackoverflow.com/questions/11929099/ + // html5-canvas-drawimage-ratio-bug-ios + if ( Base.os.ios >= 7 ) { + return function( canvas, img, x, y, w, h ) { + var iw = img.naturalWidth, + ih = img.naturalHeight, + vertSquashRatio = detectVerticalSquash( img, iw, ih ); + + return canvas.getContext('2d').drawImage( img, 0, 0, + iw * vertSquashRatio, ih * vertSquashRatio, + x, y, w, h ); + }; + } + + /** + * Detect subsampling in loaded image. + * In iOS, larger images than 2M pixels may be + * subsampled in rendering. + */ + function detectSubsampling( img ) { + var iw = img.naturalWidth, + ih = img.naturalHeight, + canvas, ctx; + + // subsampling may happen overmegapixel image + if ( iw * ih > 1024 * 1024 ) { + canvas = document.createElement('canvas'); + canvas.width = canvas.height = 1; + ctx = canvas.getContext('2d'); + ctx.drawImage( img, -iw + 1, 0 ); + + // subsampled image becomes half smaller in rendering size. + // check alpha channel value to confirm image is covering + // edge pixel or not. if alpha value is 0 + // image is not covering, hence subsampled. + return ctx.getImageData( 0, 0, 1, 1 ).data[ 3 ] === 0; + } else { + return false; + } + } + + + return function( canvas, img, x, y, width, height ) { + var iw = img.naturalWidth, + ih = img.naturalHeight, + ctx = canvas.getContext('2d'), + subsampled = detectSubsampling( img ), + doSquash = this.type === 'image/jpeg', + d = 1024, + sy = 0, + dy = 0, + tmpCanvas, tmpCtx, vertSquashRatio, dw, dh, sx, dx; + + if ( subsampled ) { + iw /= 2; + ih /= 2; + } + + ctx.save(); + tmpCanvas = document.createElement('canvas'); + tmpCanvas.width = tmpCanvas.height = d; + + tmpCtx = tmpCanvas.getContext('2d'); + vertSquashRatio = doSquash ? + detectVerticalSquash( img, iw, ih ) : 1; + + dw = Math.ceil( d * width / iw ); + dh = Math.ceil( d * height / ih / vertSquashRatio ); + + while ( sy < ih ) { + sx = 0; + dx = 0; + while ( sx < iw ) { + tmpCtx.clearRect( 0, 0, d, d ); + tmpCtx.drawImage( img, -sx, -sy ); + ctx.drawImage( tmpCanvas, 0, 0, d, d, + x + dx, y + dy, dw, dh ); + sx += d; + dx += dw; + } + sy += d; + dy += dh; + } + ctx.restore(); + tmpCanvas = tmpCtx = null; + }; + })() + }); + }); + /** + * @fileOverview Transport + * @todo 鏀寔chunked浼犺緭锛屼紭鍔匡細 + * 鍙互灏嗗ぇ鏂囦欢鍒嗘垚灏忓潡锛屾尐涓紶杈擄紝鍙互鎻愰珮澶ф枃浠舵垚鍔熺巼锛屽綋澶辫触鐨勬椂鍊欙紝涔熷彧闇�瑕侀噸浼犻偅灏忛儴鍒嗭紝 + * 鑰屼笉闇�瑕侀噸澶村啀浼犱竴娆°�傚彟澶栨柇鐐圭画浼犱篃闇�瑕佺敤chunked鏂瑰紡銆� + */ + define('runtime/html5/transport',[ + 'base', + 'runtime/html5/runtime' + ], function( Base, Html5Runtime ) { + + var noop = Base.noop, + $ = Base.$; + + return Html5Runtime.register( 'Transport', { + init: function() { + this._status = 0; + this._response = null; + }, + + send: function() { + var owner = this.owner, + opts = this.options, + xhr = this._initAjax(), + blob = owner._blob, + server = opts.server, + formData, binary, fr; + + if ( opts.sendAsBinary ) { + server += (/\?/.test( server ) ? '&' : '?') + + $.param( owner._formData ); + + binary = blob.getSource(); + } else { + formData = new FormData(); + $.each( owner._formData, function( k, v ) { + formData.append( k, v ); + }); + + formData.append( opts.fileVal, blob.getSource(), + opts.filename || owner._formData.name || '' ); + } + + if ( opts.withCredentials && 'withCredentials' in xhr ) { + xhr.open( opts.method, server, true ); + xhr.withCredentials = true; + } else { + xhr.open( opts.method, server ); + } + + this._setRequestHeader( xhr, opts.headers ); + + if ( binary ) { + xhr.overrideMimeType('application/octet-stream'); + + // android鐩存帴鍙戦�乥lob浼氬鑷存湇鍔$鎺ユ敹鍒扮殑鏄┖鏂囦欢銆� + // bug璇︽儏銆� + // https://code.google.com/p/android/issues/detail?id=39882 + // 鎵�浠ュ厛鐢╢ileReader璇诲彇鍑烘潵鍐嶉�氳繃arraybuffer鐨勬柟寮忓彂閫併�� + if ( Base.os.android ) { + fr = new FileReader(); + + fr.onload = function() { + xhr.send( this.result ); + fr = fr.onload = null; + }; + + fr.readAsArrayBuffer( binary ); + } else { + xhr.send( binary ); + } + } else { + xhr.send( formData ); + } + }, + + getResponse: function() { + return this._response; + }, + + getResponseAsJson: function() { + return this._parseJson( this._response ); + }, + + getStatus: function() { + return this._status; + }, + + abort: function() { + var xhr = this._xhr; + + if ( xhr ) { + xhr.upload.onprogress = noop; + xhr.onreadystatechange = noop; + xhr.abort(); + + this._xhr = xhr = null; + } + }, + + destroy: function() { + this.abort(); + }, + + _initAjax: function() { + var me = this, + xhr = new XMLHttpRequest(), + opts = this.options; + + if ( opts.withCredentials && !('withCredentials' in xhr) && + typeof XDomainRequest !== 'undefined' ) { + xhr = new XDomainRequest(); + } + + xhr.upload.onprogress = function( e ) { + var percentage = 0; + + if ( e.lengthComputable ) { + percentage = e.loaded / e.total; + } + + return me.trigger( 'progress', percentage ); + }; + + xhr.onreadystatechange = function() { + + if ( xhr.readyState !== 4 ) { + return; + } + + xhr.upload.onprogress = noop; + xhr.onreadystatechange = noop; + me._xhr = null; + me._status = xhr.status; + + if ( xhr.status >= 200 && xhr.status < 300 ) { + me._response = xhr.responseText; + return me.trigger('load'); + } else if ( xhr.status >= 500 && xhr.status < 600 ) { + me._response = xhr.responseText; + return me.trigger( 'error', 'server' ); + } + + + return me.trigger( 'error', me._status ? 'http' : 'abort' ); + }; + + me._xhr = xhr; + return xhr; + }, + + _setRequestHeader: function( xhr, headers ) { + $.each( headers, function( key, val ) { + xhr.setRequestHeader( key, val ); + }); + }, + + _parseJson: function( str ) { + var json; + + try { + json = JSON.parse( str ); + } catch ( ex ) { + json = {}; + } + + return json; + } + }); + }); + /** + * @fileOverview FlashRuntime + */ + define('runtime/flash/runtime',[ + 'base', + 'runtime/runtime', + 'runtime/compbase' + ], function( Base, Runtime, CompBase ) { + + var $ = Base.$, + type = 'flash', + components = {}; + + + function getFlashVersion() { + var version; + + try { + version = navigator.plugins[ 'Shockwave Flash' ]; + version = version.description; + } catch ( ex ) { + try { + version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash') + .GetVariable('$version'); + } catch ( ex2 ) { + version = '0.0'; + } + } + version = version.match( /\d+/g ); + return parseFloat( version[ 0 ] + '.' + version[ 1 ], 10 ); + } + + function FlashRuntime() { + var pool = {}, + clients = {}, + destory = this.destory, + me = this, + jsreciver = Base.guid('webuploader_'); + + Runtime.apply( me, arguments ); + me.type = type; + + + // 杩欎釜鏂规硶鐨勮皟鐢ㄨ�咃紝瀹為檯涓婃槸RuntimeClient + me.exec = function( comp, fn/*, args...*/ ) { + var client = this, + uid = client.uid, + args = Base.slice( arguments, 2 ), + instance; + + clients[ uid ] = client; + + if ( components[ comp ] ) { + if ( !pool[ uid ] ) { + pool[ uid ] = new components[ comp ]( client, me ); + } + + instance = pool[ uid ]; + + if ( instance[ fn ] ) { + return instance[ fn ].apply( instance, args ); + } + } + + return me.flashExec.apply( client, arguments ); + }; + + function handler( evt, obj ) { + var type = evt.type || evt, + parts, uid; + + parts = type.split('::'); + uid = parts[ 0 ]; + type = parts[ 1 ]; + + // console.log.apply( console, arguments ); + + if ( type === 'Ready' && uid === me.uid ) { + me.trigger('ready'); + } else if ( clients[ uid ] ) { + clients[ uid ].trigger( type.toLowerCase(), evt, obj ); + } + + // Base.log( evt, obj ); + } + + // flash鐨勬帴鍙楀櫒銆� + window[ jsreciver ] = function() { + var args = arguments; + + // 涓轰簡鑳芥崟鑾峰緱鍒般�� + setTimeout(function() { + handler.apply( null, args ); + }, 1 ); + }; + + this.jsreciver = jsreciver; + + this.destory = function() { + // @todo 鍒犻櫎姹犲瓙涓殑鎵�鏈夊疄渚� + return destory && destory.apply( this, arguments ); + }; + + this.flashExec = function( comp, fn ) { + var flash = me.getFlash(), + args = Base.slice( arguments, 2 ); + + return flash.exec( this.uid, comp, fn, args ); + }; + + // @todo + } + + Base.inherits( Runtime, { + constructor: FlashRuntime, + + init: function() { + var container = this.getContainer(), + opts = this.options, + html; + + // if not the minimal height, shims are not initialized + // in older browsers (e.g FF3.6, IE6,7,8, Safari 4.0,5.0, etc) + container.css({ + position: 'absolute', + top: '-8px', + left: '-8px', + width: '9px', + height: '9px', + overflow: 'hidden' + }); + + // insert flash object + html = '<object id="' + this.uid + '" type="application/' + + 'x-shockwave-flash" data="' + opts.swf + '" '; + + if ( Base.browser.ie ) { + html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '; + } + + html += 'width="100%" height="100%" style="outline:0">' + + '<param name="movie" value="' + opts.swf + '" />' + + '<param name="flashvars" value="uid=' + this.uid + + '&jsreciver=' + this.jsreciver + '" />' + + '<param name="wmode" value="transparent" />' + + '<param name="allowscriptaccess" value="always" />' + + '</object>'; + + container.html( html ); + }, + + getFlash: function() { + if ( this._flash ) { + return this._flash; + } + + this._flash = $( '#' + this.uid ).get( 0 ); + return this._flash; + } + + }); + + FlashRuntime.register = function( name, component ) { + component = components[ name ] = Base.inherits( CompBase, $.extend({ + + // @todo fix this later + flashExec: function() { + var owner = this.owner, + runtime = this.getRuntime(); + + return runtime.flashExec.apply( owner, arguments ); + } + }, component ) ); + + return component; + }; + + if ( getFlashVersion() >= 11.4 ) { + Runtime.addRuntime( type, FlashRuntime ); + } + + return FlashRuntime; + }); + /** + * @fileOverview FilePicker + */ + define('runtime/flash/filepicker',[ + 'base', + 'runtime/flash/runtime' + ], function( Base, FlashRuntime ) { + var $ = Base.$; + + return FlashRuntime.register( 'FilePicker', { + init: function( opts ) { + var copy = $.extend({}, opts ), + len, i; + + // 淇Flash鍐嶆病鏈夎缃畉itle鐨勬儏鍐典笅鏃犳硶寮瑰嚭flash鏂囦欢閫夋嫨妗嗙殑bug. + len = copy.accept && copy.accept.length; + for ( i = 0; i < len; i++ ) { + if ( !copy.accept[ i ].title ) { + copy.accept[ i ].title = 'Files'; + } + } + + delete copy.button; + delete copy.container; + + this.flashExec( 'FilePicker', 'init', copy ); + }, + + destroy: function() { + // todo + } + }); + }); + /** + * @fileOverview 鍥剧墖鍘嬬缉 + */ + define('runtime/flash/image',[ + 'runtime/flash/runtime' + ], function( FlashRuntime ) { + + return FlashRuntime.register( 'Image', { + // init: function( options ) { + // var owner = this.owner; + + // this.flashExec( 'Image', 'init', options ); + // owner.on( 'load', function() { + // debugger; + // }); + // }, + + loadFromBlob: function( blob ) { + var owner = this.owner; + + owner.info() && this.flashExec( 'Image', 'info', owner.info() ); + owner.meta() && this.flashExec( 'Image', 'meta', owner.meta() ); + + this.flashExec( 'Image', 'loadFromBlob', blob.uid ); + } + }); + }); + /** + * @fileOverview Transport flash瀹炵幇 + */ + define('runtime/flash/transport',[ + 'base', + 'runtime/flash/runtime', + 'runtime/client' + ], function( Base, FlashRuntime, RuntimeClient ) { + var $ = Base.$; + + return FlashRuntime.register( 'Transport', { + init: function() { + this._status = 0; + this._response = null; + this._responseJson = null; + }, + + send: function() { + var owner = this.owner, + opts = this.options, + xhr = this._initAjax(), + blob = owner._blob, + server = opts.server, + binary; + + xhr.connectRuntime( blob.ruid ); + + if ( opts.sendAsBinary ) { + server += (/\?/.test( server ) ? '&' : '?') + + $.param( owner._formData ); + + binary = blob.uid; + } else { + $.each( owner._formData, function( k, v ) { + xhr.exec( 'append', k, v ); + }); + + xhr.exec( 'appendBlob', opts.fileVal, blob.uid, + opts.filename || owner._formData.name || '' ); + } + + this._setRequestHeader( xhr, opts.headers ); + xhr.exec( 'send', { + method: opts.method, + url: server + }, binary ); + }, + + getStatus: function() { + return this._status; + }, + + getResponse: function() { + return this._response; + }, + + getResponseAsJson: function() { + return this._responseJson; + }, + + abort: function() { + var xhr = this._xhr; + + if ( xhr ) { + xhr.exec('abort'); + xhr.destroy(); + this._xhr = xhr = null; + } + }, + + destroy: function() { + this.abort(); + }, + + _initAjax: function() { + var me = this, + xhr = new RuntimeClient('XMLHttpRequest'); + + xhr.on( 'uploadprogress progress', function( e ) { + return me.trigger( 'progress', e.loaded / e.total ); + }); + + xhr.on( 'load', function() { + var status = xhr.exec('getStatus'), + err = ''; + + xhr.off(); + me._xhr = null; + + if ( status >= 200 && status < 300 ) { + me._response = xhr.exec('getResponse'); + me._responseJson = xhr.exec('getResponseAsJson'); + } else if ( status >= 500 && status < 600 ) { + me._response = xhr.exec('getResponse'); + me._responseJson = xhr.exec('getResponseAsJson'); + err = 'server'; + } else { + err = 'http'; + } + + xhr.destroy(); + xhr = null; + + return err ? me.trigger( 'error', err ) : me.trigger('load'); + }); + + xhr.on( 'error', function() { + xhr.off(); + me._xhr = null; + me.trigger( 'error', 'http' ); + }); + + me._xhr = xhr; + return xhr; + }, + + _setRequestHeader: function( xhr, headers ) { + $.each( headers, function( key, val ) { + xhr.exec( 'setRequestHeader', key, val ); + }); + } + }); + }); + /** + * @fileOverview 瀹屽叏鐗堟湰銆� + */ + define('preset/all',[ + 'base', + + // widgets + 'widgets/filednd', + 'widgets/filepaste', + 'widgets/filepicker', + 'widgets/image', + 'widgets/queue', + 'widgets/runtime', + 'widgets/upload', + 'widgets/validator', + + // runtimes + // html5 + 'runtime/html5/blob', + 'runtime/html5/dnd', + 'runtime/html5/filepaste', + 'runtime/html5/filepicker', + 'runtime/html5/imagemeta/exif', + 'runtime/html5/androidpatch', + 'runtime/html5/image', + 'runtime/html5/transport', + + // flash + 'runtime/flash/filepicker', + 'runtime/flash/image', + 'runtime/flash/transport' + ], function( Base ) { + return Base; + }); + define('webuploader',[ + 'preset/all' + ], function( preset ) { + return preset; + }); + return require('webuploader'); +}); -- Gitblit v1.8.0