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 |
|
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 |
|
91 |
|
92 |
|
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);
|
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 | };
|