`
caibinghong
  • 浏览: 153889 次
  • 性别: Icon_minigender_1
  • 来自: 福建
社区版块
存档分类
最新评论

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.id] = 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

分享到:
评论

相关推荐

    JavaScript 设计模式 安全沙箱模式

    该模式常见于YUI3库的核心实现中,它通过利用同一个构造器生成独立的实例对象,这些对象彼此之间互不影响,实现了一个安全的“沙箱”环境。通过这种方式,即便是在复杂的应用或多个开发者共同协作的环境下,也不会...

    淘宝前端架构

    1. **沙箱机制**:每个模块都在自己的沙箱环境中运行,确保模块间的隔离,避免命名冲突等问题。 2. **接口设计**:明确定义模块间如何通信,这有助于降低耦合度并简化协作流程。 #### 七、具体应用的核心框架 具体...

    淘宝2011新版首页开发实践.pdf

    此外,为了防止全局变量冲突,开发团队采用了Kissy框架1.1.6版本,并为每个模块分配了一个独立的沙箱环境。最后,通过一个统一的打包脚本`build.sh`来发布所有的JS和CSS文件,进一步减少了可能的冲突。 #### 二、...

    程序员需要知道的16件事

    3. **站点地图**:创建并维护XML站点地图(XML sitemap),通常放置于根目录下名为/sitemap.xml的文件中。 4. **规范标签**:使用标签来指定页面的主要版本,避免重复内容。 5. **分析工具**:利用Google Webmaster ...

    MUI.js:Michael 的 ;) UI 框架,点 JS

    背景MUI.JS 目前是一个沙箱,我尝试在纯 JavaScript 中尝试建模/渲染/编辑/序列化 UI。 它是我早期 UFTAM + MUI.Java 的延续,在那里我玩弄了类似的想法,但基于服务器端 Java,例如 Vaadin 作为首选的 Web UI 框架...

Global site tag (gtag.js) - Google Analytics