Skip to content

Instantly share code, notes, and snippets.

@danprince
Last active April 3, 2024 19:35
Show Gist options
  • Save danprince/e46038576345989c2559 to your computer and use it in GitHub Desktop.
Save danprince/e46038576345989c2559 to your computer and use it in GitHub Desktop.
Sandbox for Code Evaluation
var app = {};
// go through the application and find every single instance of a div
// with the class of 'sandbox'
app.bootstrap = function() {
var sandboxes = document.getElementsByClassName('sandbox');
// for each sandbox, run the createSandbox function
[].forEach.call(sandboxes, app.createSandbox);
};
// given a parent element, find the first textarea inside and
// create a sandbox around it
app.createSandbox = function(parent) {
var textarea = parent.getElementsByTagName('textarea')[0],
// create an instance of Sandbox using this textarea
sandbox = Sandbox(textarea);
parent.appendChild(sandbox.label);
};
// when the DOM loads bootstrap the application
window.addEventListener('load', app.bootstrap);
// Sandbox class
// This class is based around a textarea element, which will contain
// the code. However, it could just as easily be the DOM element for
// an Ace/Codemirror editor.
function Sandbox(textarea) {
var sandbox = {};
// create a label to show output
sandbox.label = document.createElement('label');
sandbox.label.setAttribute('class', 'output');
sandbox.label.addEventListener('click', evaluate);
// evaluate code whenever there is input into the textarea
textarea.addEventListener('input', evaluate);
sandbox.textarea = textarea;
// initial resize and evaluation
resize();
evaluate();
// resize to within the appropriate height for the textarea
function resize() {
var scrollHeight = textarea.scrollHeight;
if(scrollHeight > Sandbox.MAX_HEIGHT) {
height = Sandbox.MAX_HEIGHT;
} else if(scrollHeight < Sandbox.MIN_HEIGHT) {
height = Sandbox.MIN_HEIGHT;
} else {
height = scrollHeight;
}
textarea.style.height = height + 'px';
}
// evaluate the code within the textarea
function evaluate() {
// get the code
var src = textarea.value,
// create a console proxy (for logging to the label)
console = Sandbox.consoleProxy(sandbox.label);
// clear the output first
sandbox.label.innerText = '';
// try the eval and catch errors to send to the console
try {
/* jshint ignore:start */
eval(src);
/* jshint ignore:end */
} catch(err) {
console.error(err);
}
}
return sandbox;
}
// config
Sandbox.MAX_HEIGHT = 500;
Sandbox.MIN_HEIGHT = 50;
// A function which spoofs the native console object, by writing
// text to output elements, rather than the dev tools console.
Sandbox.consoleProxy = function(element) {
return {
log: function(message) {
message = [].join.call(arguments, ' ');
element.innerText += (message + '\n');
element.setAttribute('disabled', false);
// write to the original console too
console.log.apply(console, arguments);
},
error: function(message) {
element.setAttribute('disabled', true);
element.innerText = message;
}
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment