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); |