caibinghong 发表于 2013-2-1 11:16:55

YUI3 中的沙箱实现 方式

http://www.planabc.net/2010/04/08/study_sandbox_pattern_in_yui3/
 
简化了一下 YUI3 中的沙箱实现 方式:
 
if (typeof Sandbox === 'undefined' || !Sandbox) {    Sandbox = function(o) {        var self = this;        if (!(self instanceof Sandbox)) { // 允许没有 new 操作符的实例化            return new Sandbox(o);        } else {            self._init();            self._config(o);            // 预加载某些指定模块            /* self._setup(); */            // 返回实例本身,支持链式模式            return self;        }    };}// Sandbox的(类)静态属性Sandbox.Env = {    /* sidx: 0 , */    mods: {}};(function() {    var p, i,        SLICE         = Array.prototype.slice,        /* instances     = {}, */        time          = new Date().getTime(),        win           = window,        doc           = document;    Sandbox.prototype = {        // 格式化配置参数        // NOTE:本着简单适用的原则,取消了原先 YUI 中对 loader 的支持        _config: function(o) {            var c = this.config, i, j, m, mods;            o = o || {};            // mods = c.modules;            for (i in o) {                if (i == 'win') {                    c[i]  = o[i].contentWindow || o[i];                    c.doc = c[i].document;                } else {                    c[i]  = o[i];                }            }        },        /**         * 初始化沙箱实例         * @private         */        _init: function() {            var self  = this,                G_Env = Sandbox.Env,                Env   = self.Env;            if(!Env) {                self.Env = {                    mods: {},                    _used: {},                    _attached: {},                    _loaded: {}                };                Env = self.Env;                /* if (G_Env && self !== Sandbox ) {                    Env._sidx  = ++ G_Env.sidx;                    Env._guid = ('sandbox_' + Env._sidx + '_' + time).replace(/\./g, '_');                }                self.id = Env._guid;                instances = self; */            }            self.constructor = Sandbox;            self.config = {                win: win || {},                doc: doc || {}            };        },        // 预留预加载某些指定模块,接口可根据实际需要扩展        /* _setup: function(o) {}, */        /**         * 添加模块         * @method add         * @param name {string} 模块名         * @param fn {Function} 模块对应的函数         * @param version {string}         * @param details 可选配置:         *     requires   -  {array}  在本模块执行之前附加的必须的模块数组         *     use  - {array} 在本模块执行之后附加的模块数组         *         */        add: function(name, fn, details) {            Sandbox.Env.mods[name] = {                name: name,                fn: fn,                details: details || {}            };            return this; // chain support        },        /**         * 执行与 Sandbox 实例相关联的模块:details.requires--》fn--》details.use         * @method _attach         * @param r {array} 模块列表数组         * @private         */        _attach: function(r) {            var mods = Sandbox.Env.mods,                self = this,                attached = self.Env._attached,                i, l = r.length, name, m, fn, d, req, use;            for (i = 0; i < l; i = i+1) {                name = r[i];                m    = mods[name];                if (!attached[name] && m) {                    attached[name] = true;                    fn  = m.fn;                    d   = m.details;                    req = d.requires;                    use = d.use;                    if (req) {                        self._attach(req);                    }                    if (fn) {                        fn(self);                    }                    if (use) {                        self._attach(use);                    }                }            }        },        /**         * 绑定模块至 Sandbox 实例         * @param modules* {string} 1-n 个模块 (uses arguments array)         * @param *callback {function} callback function  如果包括,必须是最后一个参数。         *         * Sandbox().use('planabc.net')         * Sandbox().use('planabc.net',function(){})         * Sandbox().use('planabc.net','planabc.com')         * Sandbox().use('planabc.net','planabc.com',function(){})         * Sandbox().use('*'); // use all available modules         *         */        use: function() {            var self = this,                a = SLICE.call(arguments, 0),                mods = Sandbox.Env.mods,                used = self.Env._used,                loader,                firstArg = a[0],                callback = a[a.length-1],                k, i, l,                r = [],                process = function(name) {                    // 添加模块至附加的模块列表                    r.push(name);                    // 一个模块仅附加一次                    if (used[name]) {                        return;                    }                    var m = mods[name], req, use, j, jl, t, tl,                        d = m.details;                    if (m) {                        used[name] = true;                        req = d.requires;                        use = d.use;                    }                    // 附加上 requires 模块                    if (req) {                        for (j = 0,jl = req.length ; j < jl; j = j + 1) {                            process(req[j]);                        }                    }                    // 附加上 use 模块                    if (use) {                        for (t = 0, tl = use.length; t < tl; t = t + 1) {                            process(use[t]);                        }                    }                },                onComplete;            if (typeof callback === 'function') {                a.pop();            } else {                callback = null;            }            onComplete = function() {                if (callback) {                    callback(self);                }            };            // Sandbox().use('*');            if (firstArg === "*") {                a = [];                for (k in mods) {                    if (mods.hasOwnProperty(k)) {                        a.push(k);                    }                }                if (callback) {                    a.push(callback);                }                return self.use.apply(self, a);            }            l = a.length;            // 处理所有必须和附加的模块            for (i = 0; i < l; i = i + 1) {                process(a[i]);            }            self._attach(r);            onComplete();            return self; // chain support        }    };})();测试页面:http://www.planabc.net/lab/yui/sandbox.html
页: [1]
查看完整版本: YUI3 中的沙箱实现 方式