summaryrefslogtreecommitdiff
path: root/alarm/node_modules/jsdom/lib/jsdom/vm-shim.js
diff options
context:
space:
mode:
Diffstat (limited to 'alarm/node_modules/jsdom/lib/jsdom/vm-shim.js')
-rw-r--r--alarm/node_modules/jsdom/lib/jsdom/vm-shim.js106
1 files changed, 106 insertions, 0 deletions
diff --git a/alarm/node_modules/jsdom/lib/jsdom/vm-shim.js b/alarm/node_modules/jsdom/lib/jsdom/vm-shim.js
new file mode 100644
index 0000000..185679e
--- /dev/null
+++ b/alarm/node_modules/jsdom/lib/jsdom/vm-shim.js
@@ -0,0 +1,106 @@
+"use strict";
+/* eslint-disable no-new-func */
+const acorn = require("acorn");
+const findGlobals = require("acorn-globals");
+const escodegen = require("escodegen");
+const jsGlobals = require("./browser/js-globals.json");
+
+// We can't use the default browserify vm shim because it doesn't work in a web worker.
+
+// "eval" is skipped because it's set to a function that calls `runInContext`:
+const jsGlobalEntriesToInstall = Object.entries(jsGlobals).filter(([name]) => name !== "eval" && name in global);
+
+exports.createContext = function (sandbox) {
+ // TODO: This should probably use a symbol
+ Object.defineProperty(sandbox, "__isVMShimContext", {
+ value: true,
+ writable: true,
+ configurable: true,
+ enumerable: false
+ });
+
+ for (const [globalName, globalPropDesc] of jsGlobalEntriesToInstall) {
+ const propDesc = { ...globalPropDesc, value: global[globalName] };
+ Object.defineProperty(sandbox, globalName, propDesc);
+ }
+
+ Object.defineProperty(sandbox, "eval", {
+ value(code) {
+ return exports.runInContext(code, sandbox);
+ },
+ writable: true,
+ configurable: true,
+ enumerable: false
+ });
+};
+
+exports.isContext = function (sandbox) {
+ return sandbox.__isVMShimContext;
+};
+
+exports.runInContext = function (code, contextifiedSandbox, options) {
+ if (code === "this") {
+ // Special case for during window creation.
+ return contextifiedSandbox;
+ }
+
+ if (options === undefined) {
+ options = {};
+ }
+
+ const comments = [];
+ const tokens = [];
+ const ast = acorn.parse(code, {
+ allowReturnOutsideFunction: true,
+ ranges: true,
+ // collect comments in Esprima's format
+ onComment: comments,
+ // collect token ranges
+ onToken: tokens
+ });
+
+ // make sure we keep comments
+ escodegen.attachComments(ast, comments, tokens);
+
+ const globals = findGlobals(ast);
+ for (let i = 0; i < globals.length; ++i) {
+ if (globals[i].name === "window" || globals[i].name === "this") {
+ continue;
+ }
+
+ const { nodes } = globals[i];
+ for (let j = 0; j < nodes.length; ++j) {
+ const { type, name } = nodes[j];
+ nodes[j].type = "MemberExpression";
+ nodes[j].property = { name, type };
+ nodes[j].computed = false;
+ nodes[j].object = {
+ name: "window",
+ type: "Identifier"
+ };
+ }
+ }
+
+ const lastNode = ast.body[ast.body.length - 1];
+ if (lastNode.type === "ExpressionStatement") {
+ lastNode.type = "ReturnStatement";
+ lastNode.argument = lastNode.expression;
+ delete lastNode.expression;
+ }
+
+ const rewrittenCode = escodegen.generate(ast, { comment: true });
+ const suffix = options.filename !== undefined ? "\n//# sourceURL=" + options.filename : "";
+
+ return Function("window", rewrittenCode + suffix).bind(contextifiedSandbox)(contextifiedSandbox);
+};
+
+exports.Script = class VMShimScript {
+ constructor(code, options) {
+ this._code = code;
+ this._options = options;
+ }
+
+ runInContext(sandbox, options) {
+ return exports.runInContext(this._code, sandbox, { ...this._options, ...options });
+ }
+};