Last active
April 3, 2024 19:35
-
-
Save danprince/e46038576345989c2559 to your computer and use it in GitHub Desktop.
Sandbox for Code Evaluation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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