JSFiddle - React, Tailwind, and code Playground
HTML
<textarea>
alert("This is some user code being evaluated in a sandbox.");
alert("We can't access the global scope using this.\nFor example (this.document): " + this.document);
alert("We have also created local window and document variables.\nFor example (document.querySelector): " + document.querySelector);
~function () {
alert("Unfortunately the user may still access the global scope in other functions.\nFor example (this.document): " + this.document);
}();
alert("Oh well. I guess that's as 'foolproof' as it gets.\nYou'll need to make your own window and document objects though.");
</textarea>
JavaScript
// create our own local versions of window and document with limited functionality
var locals = {
window: {
},
document: {
}
};
var that = Object.create(null); // create our own this object for the user code
var code = document.querySelector("textarea").value; // get the user code
var sandbox = createSandbox(code, that, locals); // create a sandbox
sandbox(); // call the user code in the sandbox
function createSandbox(code, that, locals) {
var params = []; // the names of local variables
var args = []; // the local variables
for (var param in locals) {
if (locals.hasOwnProperty(param)) {
args.push(locals[param]);
params.push(param);
}
}
var context = Array.prototype.concat.call(that, params, code); // create the parameter list for the sandbox
var sandbox = new (Function.prototype.bind.apply(Function, context)); // create the sandbox function
context = Array.prototype.concat.call(that, args); // create the argument list for the sandbox
return Function.prototype.bind.apply(sandbox, context); // bind the local variables to the sandbox
}