Skip to content

Added Context to emulate node behaviour #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 53 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,42 @@ var forEach = function (xs, fn) {
}
};

var defineProp = (function() {
try {
Object.defineProperty({}, '_', {});
return function(obj, name, value) {
Object.defineProperty(obj, name, {
writable: true,
enumerable: false,
configurable: true,
value: value
})
};
} catch(e) {
return function(obj, name, value) {
obj[name] = value;
};
}
}());

var globals = ['Array', 'Boolean', 'Date', 'Error', 'EvalError', 'Function',
'Infinity', '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() {}
Context.prototype = {};

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 = {};
Script.prototype.runInContext = function (context) {
if (!(context instanceof Context)) {
throw new TypeError("needs a 'context' argument.");
}

var iframe = document.createElement('iframe');
if (!iframe.style) iframe.style = {};
Expand All @@ -35,7 +64,12 @@ Script.prototype.runInNewContext = function (context) {
forEach(Object_keys(context), function (key) {
win[key] = context[key];
});

forEach(globals, function (key) {
if (context[key]) {
win[key] = context[key];
}
});

if (!win.eval && win.execScript) {
// win.eval() magically appears when this is called in IE:
win.execScript('null');
Expand All @@ -53,6 +87,12 @@ Script.prototype.runInNewContext = function (context) {
context[key] = win[key];
}
});

forEach(globals, function (key) {
if (!(key in context)) {
defineProp(context, key, win[key]);
}
});

document.body.removeChild(iframe);

Expand All @@ -63,11 +103,15 @@ Script.prototype.runInThisContext = function () {
return eval(this.code); // maybe...
Copy link

@marafee1243 marafee1243 Mar 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Firefox : 65.0.1
throws error where as Chrome doesnt.

Content Security Policy: The page’s settings blocked the loading of a resource at eval (“script-src”).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are using a CSP header that does not allow eval as script-src, compliant browsers will throw an error and not let you use eval. This is working as intended.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also way to gravedig an unrelated PR with an issue that isn't even related to the project directly. Please don't do that.

};

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);
Script.prototype.runInNewContext = function (context) {
var ctx = Script.createContext(context);
var res = this.runInContext(ctx);

forEach(Object_keys(ctx), function (key) {
context[key] = ctx[key];
});

return res;
};

forEach(Object_keys(Script.prototype), function (name) {
Expand All @@ -82,9 +126,7 @@ exports.createScript = function (code) {
};

exports.createContext = Script.createContext = function (context) {
// not really sure what this one does
// seems to just make a shallow copy
var copy = {};
var copy = new Context();
if(typeof context === 'object') {
forEach(Object_keys(context), function (key) {
copy[key] = context[key];
Expand Down