var Object_keys = function (obj) { if (Object.keys) return Object.keys(obj) else { var res = []; for (var key in obj) res.push(key) return res; } }; var forEach = function (xs, fn) { if (xs.forEach) return xs.forEach(fn) else for (var i = 0; i < xs.length; i++) { fn(xs[i], i, xs); } }; var Script = exports.Script = function NodeScript (code) { if (!(this instanceof Script)) return new Script(code); this.code = code; }; Script.prototype.runInNewContext = function (context) { if (!context) context = {}; var iframe = document.createElement('iframe'); if (!iframe.style) iframe.style = {}; iframe.style.display = 'none'; document.body.appendChild(iframe); var win = iframe.contentWindow; forEach(Object_keys(context), function (key) { win[key] = context[key]; }); if (!win.eval && win.execScript) { // win.eval() magically appears when this is called in IE: win.execScript('null'); } var res = win.eval(this.code); forEach(Object_keys(win), function (key) { context[key] = win[key]; }); document.body.removeChild(iframe); return res; }; Script.prototype.runInThisContext = function () { return eval(this.code); // maybe... }; Script.prototype.runInContext = function (context) { // seems to be just runInNewContext on magical context objects which are // otherwise indistinguishable from objects except plain old objects // for the parameter segfaults node return this.runInNewContext(context); }; forEach(Object_keys(Script.prototype), function (name) { exports[name] = Script[name] = function (code) { var s = Script(code); return s[name].apply(s, [].slice.call(arguments, 1)); }; }); exports.createScript = function (code) { return exports.Script(code); }; exports.createContext = Script.createContext = function (context) { // not really sure what this one does // seems to just make a shallow copy var copy = {}; if(typeof context === 'object') { forEach(Object_keys(context), function (key) { copy[key] = context[key]; }); } return copy; };