Projekt

Obecné

Profil

Stáhnout (3.98 KB) Statistiky
| Větev: | Revize:
1
var indexOf = function (xs, item) {
2
    if (xs.indexOf) return xs.indexOf(item);
3
    else for (var i = 0; i < xs.length; i++) {
4
        if (xs[i] === item) return i;
5
    }
6
    return -1;
7
};
8
var Object_keys = function (obj) {
9
    if (Object.keys) return Object.keys(obj)
10
    else {
11
        var res = [];
12
        for (var key in obj) res.push(key)
13
        return res;
14
    }
15
};
16

    
17
var forEach = function (xs, fn) {
18
    if (xs.forEach) return xs.forEach(fn)
19
    else for (var i = 0; i < xs.length; i++) {
20
        fn(xs[i], i, xs);
21
    }
22
};
23

    
24
var defineProp = (function() {
25
    try {
26
        Object.defineProperty({}, '_', {});
27
        return function(obj, name, value) {
28
            Object.defineProperty(obj, name, {
29
                writable: true,
30
                enumerable: false,
31
                configurable: true,
32
                value: value
33
            })
34
        };
35
    } catch(e) {
36
        return function(obj, name, value) {
37
            obj[name] = value;
38
        };
39
    }
40
}());
41

    
42
var globals = ['Array', 'Boolean', 'Date', 'Error', 'EvalError', 'Function',
43
'Infinity', 'JSON', 'Math', 'NaN', 'Number', 'Object', 'RangeError',
44
'ReferenceError', 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError',
45
'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape',
46
'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'undefined', 'unescape'];
47

    
48
function Context() {}
49
Context.prototype = {};
50

    
51
var Script = exports.Script = function NodeScript (code) {
52
    if (!(this instanceof Script)) return new Script(code);
53
    this.code = code;
54
};
55

    
56
Script.prototype.runInContext = function (context) {
57
    if (!(context instanceof Context)) {
58
        throw new TypeError("needs a 'context' argument.");
59
    }
60
    
61
    var iframe = document.createElement('iframe');
62
    if (!iframe.style) iframe.style = {};
63
    iframe.style.display = 'none';
64
    
65
    document.body.appendChild(iframe);
66
    
67
    var win = iframe.contentWindow;
68
    var wEval = win.eval, wExecScript = win.execScript;
69

    
70
    if (!wEval && wExecScript) {
71
        // win.eval() magically appears when this is called in IE:
72
        wExecScript.call(win, 'null');
73
        wEval = win.eval;
74
    }
75
    
76
    forEach(Object_keys(context), function (key) {
77
        win[key] = context[key];
78
    });
79
    forEach(globals, function (key) {
80
        if (context[key]) {
81
            win[key] = context[key];
82
        }
83
    });
84
    
85
    var winKeys = Object_keys(win);
86

    
87
    var res = wEval.call(win, this.code);
88
    
89
    forEach(Object_keys(win), function (key) {
90
        // Avoid copying circular objects like `top` and `window` by only
91
        // updating existing context properties or new properties in the `win`
92
        // that was only introduced after the eval.
93
        if (key in context || indexOf(winKeys, key) === -1) {
94
            context[key] = win[key];
95
        }
96
    });
97

    
98
    forEach(globals, function (key) {
99
        if (!(key in context)) {
100
            defineProp(context, key, win[key]);
101
        }
102
    });
103
    
104
    document.body.removeChild(iframe);
105
    
106
    return res;
107
};
108

    
109
Script.prototype.runInThisContext = function () {
110
    return eval(this.code); // maybe...
111
};
112

    
113
Script.prototype.runInNewContext = function (context) {
114
    var ctx = Script.createContext(context);
115
    var res = this.runInContext(ctx);
116

    
117
    if (context) {
118
        forEach(Object_keys(ctx), function (key) {
119
            context[key] = ctx[key];
120
        });
121
    }
122

    
123
    return res;
124
};
125

    
126
forEach(Object_keys(Script.prototype), function (name) {
127
    exports[name] = Script[name] = function (code) {
128
        var s = Script(code);
129
        return s[name].apply(s, [].slice.call(arguments, 1));
130
    };
131
});
132

    
133
exports.isContext = function (context) {
134
    return context instanceof Context;
135
};
136

    
137
exports.createScript = function (code) {
138
    return exports.Script(code);
139
};
140

    
141
exports.createContext = Script.createContext = function (context) {
142
    var copy = new Context();
143
    if(typeof context === 'object') {
144
        forEach(Object_keys(context), function (key) {
145
            copy[key] = context[key];
146
        });
147
    }
148
    return copy;
149
};
(4-4/7)