1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 | function Object_keys(obj) {
|
8 | if (Object.keys) return Object.keys(obj)
|
9 | else {
|
10 | var res = [];
|
11 | for (var key in obj) res.push(key)
|
12 | return res;
|
13 | }
|
14 | }
|
15 |
|
16 | function forEach(xs, fn) {
|
17 | if (xs.forEach) return xs.forEach(fn)
|
18 | else
|
19 | for (var i = 0; i < xs.length; i++) {
|
20 | fn(xs[i], i, xs);
|
21 | }
|
22 | }
|
23 | var _defineProp;
|
24 |
|
25 | function defineProp(obj, name, value) {
|
26 | if (typeof _defineProp !== 'function') {
|
27 | _defineProp = createDefineProp;
|
28 | }
|
29 | _defineProp(obj, name, value);
|
30 | }
|
31 |
|
32 | function createDefineProp() {
|
33 | try {
|
34 | Object.defineProperty({}, '_', {});
|
35 | return function(obj, name, value) {
|
36 | Object.defineProperty(obj, name, {
|
37 | writable: true,
|
38 | enumerable: false,
|
39 | configurable: true,
|
40 | value: value
|
41 | })
|
42 | };
|
43 | } catch (e) {
|
44 | return function(obj, name, value) {
|
45 | obj[name] = value;
|
46 | };
|
47 | }
|
48 | }
|
49 |
|
50 | var globals = ['Array', 'Boolean', 'Date', 'Error', 'EvalError', 'Function',
|
51 | 'Infinity', 'JSON', 'Math', 'NaN', 'Number', 'Object', 'RangeError',
|
52 | 'ReferenceError', 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError',
|
53 | 'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape',
|
54 | 'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'undefined', 'unescape'
|
55 | ];
|
56 |
|
57 | function Context() {}
|
58 | Context.prototype = {};
|
59 |
|
60 | export function Script(code) {
|
61 | if (!(this instanceof Script)) return new Script(code);
|
62 | this.code = code;
|
63 | }
|
64 | function otherRunInContext(code, context) {
|
65 | var args = Object_keys(global);
|
66 | args.push('with (this.__ctx__){return eval(this.__code__)}');
|
67 | var fn = Function.apply(null, args);
|
68 | return fn.apply({
|
69 | __code__: code,
|
70 | __ctx__: context
|
71 | });
|
72 | }
|
73 | Script.prototype.runInContext = function(context) {
|
74 | if (!(context instanceof Context)) {
|
75 | throw new TypeError('needs a \'context\' argument.');
|
76 | }
|
77 | if (global.document) {
|
78 | var iframe = global.document.createElement('iframe');
|
79 | if (!iframe.style) iframe.style = {};
|
80 | iframe.style.display = 'none';
|
81 |
|
82 | global.document.body.appendChild(iframe);
|
83 |
|
84 | var win = iframe.contentWindow;
|
85 | var wEval = win.eval,
|
86 | wExecScript = win.execScript;
|
87 |
|
88 | if (!wEval && wExecScript) {
|
89 |
|
90 | wExecScript.call(win, 'null');
|
91 | wEval = win.eval;
|
92 | }
|
93 |
|
94 | forEach(Object_keys(context), function(key) {
|
95 | win[key] = context[key];
|
96 | });
|
97 | forEach(globals, function(key) {
|
98 | if (context[key]) {
|
99 | win[key] = context[key];
|
100 | }
|
101 | });
|
102 |
|
103 | var winKeys = Object_keys(win);
|
104 |
|
105 | var res = wEval.call(win, this.code);
|
106 |
|
107 | forEach(Object_keys(win), function(key) {
|
108 |
|
109 |
|
110 |
|
111 | if (key in context || indexOf(winKeys, key) === -1) {
|
112 | context[key] = win[key];
|
113 | }
|
114 | });
|
115 |
|
116 | forEach(globals, function(key) {
|
117 | if (!(key in context)) {
|
118 | defineProp(context, key, win[key]);
|
119 | }
|
120 | });
|
121 | global.document.body.removeChild(iframe);
|
122 |
|
123 | return res;
|
124 | }
|
125 | return otherRunInContext(this.code, context);
|
126 | };
|
127 |
|
128 | Script.prototype.runInThisContext = function() {
|
129 | var fn = new Function('code', 'return eval(code);');
|
130 | return fn.call(global, this.code);
|
131 | };
|
132 |
|
133 | Script.prototype.runInNewContext = function(context) {
|
134 | var ctx = createContext(context);
|
135 | var res = this.runInContext(ctx);
|
136 | if (context) {
|
137 | forEach(Object_keys(ctx), function(key) {
|
138 | context[key] = ctx[key];
|
139 | });
|
140 | }
|
141 |
|
142 | return res;
|
143 | };
|
144 |
|
145 | export function createScript(code) {
|
146 | return new Script(code);
|
147 | }
|
148 |
|
149 | export function createContext(context) {
|
150 | if (isContext(context)) {
|
151 | return context;
|
152 | }
|
153 | var copy = new Context();
|
154 | if (typeof context === 'object') {
|
155 | forEach(Object_keys(context), function(key) {
|
156 | copy[key] = context[key];
|
157 | });
|
158 | }
|
159 | return copy;
|
160 | }
|
161 | export function runInContext(code, contextifiedSandbox, options) {
|
162 | var script = new Script(code, options);
|
163 | return script.runInContext(contextifiedSandbox, options);
|
164 | }
|
165 | export function runInThisContext(code, options) {
|
166 | var script = new Script(code, options);
|
167 | return script.runInThisContext(options);
|
168 | }
|
169 | export function isContext(context) {
|
170 | return context instanceof Context;
|
171 | }
|
172 | export function runInNewContext(code, sandbox, options) {
|
173 | var script = new Script(code, options);
|
174 | return script.runInNewContext(sandbox, options);
|
175 | }
|
176 | export default {
|
177 | runInContext: runInContext,
|
178 | isContext: isContext,
|
179 | createContext: createContext,
|
180 | createScript: createScript,
|
181 | Script: Script,
|
182 | runInThisContext: runInThisContext,
|
183 | runInNewContext: runInNewContext
|
184 | }
|
185 |
|
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 | var _indexOf = [].indexOf;
|
192 |
|
193 | function indexOf(arr, obj){
|
194 | if (_indexOf) return arr.indexOf(obj);
|
195 | for (var i = 0; i < arr.length; ++i) {
|
196 | if (arr[i] === obj) return i;
|
197 | }
|
198 | return -1;
|
199 | }
|