解決辦法

1.高版本的webuploader.js會出現這種情況,改為低版本webuploader.js可以解決這個問題
2.隱藏這行capture=camera,用編輯器開啟webupload.js 4926 行

以下是低版本的webuploader.js,複製儲存為webuploader.js,覆蓋原js即可

/*! WebUploader 0.1.5 */


/**
 * @fileOverview 讓內部各個部件的程式碼可以用[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,暫時不支援不指定id.
        _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;
        },

        // 將所有modules,將路徑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 ];
            }

            return obj;
        },

        makeExport = function( dollar ) {
            root.__dollar = dollar;

            // exports every module.
            return exportsTo( factory( root, _define, _require ) );
        },

        origin;

    if ( typeof module === 'object' && typeof module.exports === 'object' ) {

        // For CommonJS and CommonJS-like environments where a proper window is present,
        module.exports = makeExport();
    } 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([ 'jquery' ], makeExport );
    } else {

        // Browser globals case. Just assign the
        // result to a property on the global.
        origin = root.WebUploader;
        root.WebUploader = makeExport();
        root.WebUploader.noConflict = function() {
            root.WebUploader = origin;
        };
    }
})( window, function( window, define, require ) {


    /**
     * @fileOverview jQuery or Zepto
     */
    define('dollar-third',[],function() {
        var $ = window.__dollar || window.jQuery || window.Zepto;

        if ( !$ ) {
            throw new Error('jQuery or Zepto not found!');
        }

        return $;
    });
    /**
     * @fileOverview Dom 操作相關
     */
    define('dollar',[
        'dollar-third'
    ], function( _ ) {
        return _;
    });
    /**
     * @fileOverview 使用jQuery的Promise
     */
    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`:WebUploader.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.5',

            /**
             * @property {jQuery|Zepto} $ 引用依賴的jQuery或者Zepto物件。
             */
            $: $,

            Deferred: promise.Deferred,

            isPromise: promise.isPromise,

            when: promise.when,

            /**
             * @description  簡單的瀏覽器檢查結果。
             *
             * * `webkit`  webkit版本號,如果瀏覽器為非webkit核心,此屬性為`undefined`。
             * * `chrome`  chrome瀏覽器版本號,如果瀏覽器為chrome,此屬性為`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`  如果在android瀏覽器環境下,此值為對應的android版本號,否則為`undefined`。
             * * `ios` 如果在ios瀏覽器環境下,此值為對應的ios版本號,否則為`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;

                // 構建原型,新增原型方法或屬性。
                // 暫時用Object.create實現。
                child.prototype = createObject( Super.prototype );
                protos && $.extend( true, child.prototype, protos );

                return child;
            },

            /**
             * 一個不做任何事情的方法。可以用來賦值給預設的callback.
             * @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如果存在的話,否則引用一個[空函式noop](#WebUploader:Base.noop)。
             * @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)的陣列slice方法。
             * 將用來將非陣列物件轉化成陣列物件。
             * @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 ),

            /**
             * 生成唯一的ID
             * @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(千位元組),同時檔案大小大於M, 此方法的輸出將還是顯示成多少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;

        // 根據條件過濾出事件handlers.
        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 ) {
            // 不支援物件,只支援多個event用空格隔開
            $.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`方法在執行時,arguments將會來源於trigger的時候攜帶的引數。如
             * ```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`的優先順序比腳低,會再正常`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;
            },

            /**
             * 繫結事件,且當handler執行完後,自動解除繫結。
             * @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;
            },

            /**
             * 解除事件繫結
             * @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中return false了,則返回false, 否則返回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)方法,使任何物件具備事件行為。
         * 主要目的是負責模組與模組之間的合作,降低耦合度。
         *
         * @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',
            cancelFile: 'cancel-file',
            skipFile: 'skip-file',
            retry: 'retry',
            isInProgress: 'is-in-progress',
            makeThumb: 'make-thumb',
            md5File: 'md5-file',
            getDimension: 'get-dimension',
            addButton: 'add-btn',
            predictRuntimeType: 'predict-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');
                });
            },

            /**
             * 獲取或者設定Uploader配置項。
             * @method option
             * @grammar option( key ) => *
             * @grammar option( key, val ) => self
             * @example
             *
             * // 初始狀態圖片上傳前不會壓縮
             * var uploader = new WebUploader.Uploader({
             *     compress: null;
             * });
             *
             * // 修改後圖片上傳前,嘗試將圖片壓縮到1600 * 1600
             * uploader.option( 'compress', {
             *     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` 上傳成功的檔案數
             * * `progressNum` 上傳中的檔案數
             * * `cancelNum` 被刪除的檔案數
             * * `invalidNum` 無效的檔案數
             * * `uploadFailNum` 上傳失敗的檔案數
             * * `queueNum` 還在佇列中的檔案數
             * * `interruptNum` 被暫停的檔案數
             * @method getStats
             * @grammar getStats() => Object
             */
            getStats: function() {
                // return this._mgr.getStats.apply( this._mgr, arguments );
                var stats = this.request('get-stats');

                return stats ? {
                    successNum: stats.numOfSuccess,
                    progressNum: stats.numOfProgress,

                    // who care?
                    // queueFailNum: 0,
                    cancelNum: stats.numOfCancel,
                    invalidNum: stats.numOfInvalid,
                    uploadFailNum: stats.numOfUploadFailed,
                    queueNum: stats.numOfQueue,
                    interruptNum: stats.numofInterrupt
                } : {};
            },

            // 需要重寫此方法來來支援opts.onEvent和instance.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方法註冊的handler.
                        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 ||

                        // 廣播所有uploader的事件。
                        Mediator.trigger.apply( Mediator,
                        [ this, type ].concat( args ) ) === false ) {

                    return false;
                }

                return true;
            },

            /**
             * 銷燬 webuploader 例項
             * @method destroy
             * @grammar destroy() => undefined
             */
            destroy: function() {
                this.request( 'destroy', arguments );
                this.off();
            },

            // widgets/widget.js將補充此方法的詳細文件。
            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 = {},

            // 獲取物件的第一個key
            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;
                this._parent = parent;
                return container;
            },

            init: Base.noop,
            exec: Base.noop,

            destroy: function() {
                this._container && this._container.remove();
                this._parent && this._parent.removeClass('webuploader-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 ) {
                        // 有些型別不能重用,比如filepicker.
                        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 );
                }

                // 像filePicker只能獨立存在,不能公用。
                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');
                });
            }
        });

        Mediator.installTo( DragAndDrop.prototype );

        return DragAndDrop;
    });
    /**
     * @fileOverview 元件基類。
     */
    define('widgets/widget',[
        'base',
        'uploader'
    ], function( Base, Uploader ) {

        var $ = Base.$,
            _init = Uploader.prototype._init,
            _destroy = Uploader.prototype.destroy,
            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,

            // 類Backbone的事件監聽宣告,監聽uploader例項上的事件
            // widget直接無法監聽事件,事件只能通過uploader來傳遞
            invoke: function( apiName, args ) {

                /*
                    {
                        'make-thumb': 'makeThumb'
                    }
                 */
                var map = this.responseMap;

                // 如果無API響應宣告則忽略
                if ( !map || !(apiName in map) || !(map[ apiName ] in this) ||
                        !$.isFunction( this[ map[ apiName ] ] ) ) {

                    return