| Index: lib/snippets.js |
| =================================================================== |
| --- a/lib/snippets.js |
| +++ b/lib/snippets.js |
| @@ -160,23 +160,60 @@ |
| * @param {string[]} libraries |
| * @return {string} |
| */ |
| function compileScript(script, libraries) |
| { |
| return ` |
| "use strict"; |
| { |
| + let globals = {}; |
| + |
| + for (let name of typeof window != "undefined" ? Object.keys(window) : []) |
|
Manish Jethani
2018/07/31 14:17:08
Shadow globals on the window object (browser).
(Draft)
2018/09/24 11:31:55
Nit: I think checking if `window` is undefined first, before the loop would be
easier to grok.
Edit
|
| + globals[name] = null; |
| + |
| + for (let name of typeof global != "undefined" ? Object.keys(global) : []) |
|
Manish Jethani
2018/07/31 14:17:08
Shadow globals on the global object (Node.js, for
|
| + globals[name] = null; |
| + |
| + if (typeof browser != "undefined") |
| + { |
| + globals.browser = { |
|
Manish Jethani
2018/07/31 14:17:08
Expose only certain extension APIs.
|
| + runtime: { |
| + getURL: browser.runtime.getURL |
| + } |
| + }; |
| + } |
| + |
| + if (typeof document != "undefined") |
| + { |
| + globals.document = new Proxy(document, { |
|
Manish Jethani
2018/07/31 14:17:08
Make document object available with restricted acc
Manish Jethani
2018/07/31 14:17:08
Use a Proxy object here so it is transparent to th
|
| + get(target, property) |
| + { |
| + if (property == "defaultView") |
|
Manish Jethani
2018/07/31 14:17:08
Prevent access to the window object.
|
| + return null; |
| + |
| + let value = target[property]; |
| + if (typeof value == "function") |
| + return value.bind(target); |
|
Manish Jethani
2018/07/31 14:17:08
Bind the function to the target so its `this` is t
|
| + |
| + return value; |
| + } |
| + }); |
| + } |
| + |
| const libraries = ${JSON.stringify(libraries)}; |
| const script = ${JSON.stringify(parseScript(script))}; |
| let imports = Object.create(null); |
| for (let library of libraries) |
| - new Function("exports", library)(imports); |
| + { |
| + let func = new Function("exports", ...Object.keys(globals), library); |
|
Manish Jethani
2018/07/31 14:17:08
Pass the globals as arguments to the snippet libra
|
| + func(imports, ...Object.keys(globals).map(key => globals[key])); |
| + } |
| for (let [name, ...args] of script) |
| { |
| if (Object.prototype.hasOwnProperty.call(imports, name)) |
| { |
| let value = imports[name]; |
| if (typeof value == "function") |
| value(...args); |