diff --git a/index.js b/index.js index 644efd1..971c8b6 100644 --- a/index.js +++ b/index.js @@ -35,12 +35,26 @@ var defineProp = (function() { }()); var globals = ['Array', 'Boolean', 'Date', 'Error', 'EvalError', 'Function', -'Infinity', 'JSON', 'Math', 'NaN', 'Number', 'Object', 'RangeError', +'JSON', 'Math', 'NaN', 'Number', 'Object', 'RangeError', 'ReferenceError', 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError', 'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape', 'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'undefined', 'unescape']; -function Context() {} +function Context() { + + var iframe = document.createElement('iframe'); + if (!iframe.style) iframe.style = {}; + iframe.style.display = 'none'; + + document.body.appendChild(iframe); + + Object.defineProperty(this, "_iframe", { + enumerable: false, + writable: true + }); + + this._iframe = iframe; +} Context.prototype = {}; var Script = exports.Script = function NodeScript (code) { @@ -53,13 +67,7 @@ Script.prototype.runInContext = function (context) { throw new TypeError("needs a 'context' argument."); } - var iframe = document.createElement('iframe'); - if (!iframe.style) iframe.style = {}; - iframe.style.display = 'none'; - - document.body.appendChild(iframe); - - var win = iframe.contentWindow; + var win = context._iframe.contentWindow; var wEval = win.eval, wExecScript = win.execScript; if (!wEval && wExecScript) { @@ -67,7 +75,7 @@ Script.prototype.runInContext = function (context) { wExecScript.call(win, 'null'); wEval = win.eval; } - + forEach(Object_keys(context), function (key) { win[key] = context[key]; }); @@ -95,9 +103,6 @@ Script.prototype.runInContext = function (context) { defineProp(context, key, win[key]); } }); - - document.body.removeChild(iframe); - return res; }; @@ -132,7 +137,12 @@ exports.createContext = Script.createContext = function (context) { if(typeof context === 'object') { forEach(Object_keys(context), function (key) { copy[key] = context[key]; + copy._iframe.contentWindow[key] = context[key]; }); } return copy; }; + +exports.isContext = function(sandbox){ + return sandbox instanceof Context; +}; diff --git a/package.json b/package.json index dd948a2..1ce62dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "vm-browserify", - "version": "0.0.4", + "name": "vm-browserify2", + "version": "0.0.6", "description": "vm module for the browser", "main": "index.js", "repository": { diff --git a/test/vm.js b/test/vm.js index ea8cd31..d50fa3c 100644 --- a/test/vm.js +++ b/test/vm.js @@ -33,3 +33,27 @@ test('vmRunInContext', function (t) { vm.runInContext('var y = 1', context); t.deepEqual(context, { foo: 1, x: 1, y: 1 }); }); + + +test('vmRunInContext with closure', function (t) { + t.plan(4); + + var context = vm.createContext(); + + vm.runInContext('var x = 1', context); + t.deepEqual(context, { x: 1 }); + + vm.runInContext('function y() { return ++x; }', context); + var x = vm.runInContext('y()', context); + t.equal(x, 2); + t.equal(context.x, 2); + t.equal(typeof context.y, 'function'); +}); + +test('isContext', function (t) { + t.plan(2); + + var context = vm.createContext(); + t.true(vm.isContext(context)); + t.false(vm.isContext({})); +});