-
Notifications
You must be signed in to change notification settings - Fork 2
/
sandbox.js
65 lines (54 loc) · 1.54 KB
/
sandbox.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
const rawWindow = window;
function exeCode(code, sandbox) {
window.__MICRO_TOY_CONTEXT__ = sandbox.global;
const _code = `;(function(window, self) {
with(window) {
${code}
}
}).call(window.__MICRO_TOY_CONTEXT__, window.__MICRO_TOY_CONTEXT__, window.__MICRO_TOY_CONTEXT__);`
// 规避with严格模式的问题。 new Funciton -- vuejs template complier
try {
(0, eval)(_code);
sandbox.isRun = true;
} catch (error) {
console.error(`[micro-toy sandbox] ${error}`);
}
}
export function createSandbox() {
const fakeWindow = {};
const sandbox = {
global: {},
run, // script run window inject
stop,
isRun: false
};
function run (code) {
// 访问fakeWindow的属性, 没有的话,从全局window取。
// 设置fakeWindow的属性,设置到fakewindow上。
sandbox.global = new Proxy(fakeWindow, {
get(target, key) {
if (Reflect.has(target, key)) {
return Reflect.get(target, key);
}
const rawValue = Reflect.get(rawWindow, key);
// console alert
if (typeof rawValue === 'function') {
const valueStr = rawValue.toString();
if (!/^function\s+[A-Z]/.test(valueStr) && !/^class\s+/.test(valueStr)) {
return rawValue.bind(rawWindow);
}
}
return rawValue;
},
set(target, key, value) {
target[key] = value;
return true;
}
})
exeCode(code, sandbox);
}
function stop() {
sandbox.isRun = false;
}
return sandbox;
}