Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to create a console in JavaScript that provides a persistent local scope?

I'd like to create a console (think chrome's dev console), in JavaScript for a web application, that has a persistent scope. So you would be able to say, set a variable, and then access that variable later in the console. Is there an easy way to do this in JavaScript?

An example session:

var x = SomeCustomFunction()
>> "the result"
x.slice(4)
>> "result"
like image 655
B T Avatar asked Aug 08 '15 22:08

B T


3 Answers

You can use indirect calls to eval.

Direct calls won't work because they would use the calling execution context, which will probably change between creating the variable and attempting to access it.

Instead, indirect calls to eval will use the global execution context, and thus the variables will persist.

Some ways to make indirect calls to eval are using var myEval = eval; myEval(...) or window.eval(...).

var input = document.getElementById('input'),
    data = document.getElementById('data');
document.getElementById('form').onsubmit = function() {
  var code = input.value,
      result = window.eval(code);
  data.appendChild(document.createElement('dt')).appendChild(document.createTextNode(code));
  data.appendChild(document.createElement('dd')).appendChild(document.createTextNode(result));
  return false;
};
<form id="form">
  <dl id="data"></dl>
  <input id="input" />
  <input type="submit" />
</form>

For example, in the snippet above, enter var x = 5. Then enter x, and you will receive 5.

like image 124
Oriol Avatar answered Oct 28 '22 02:10

Oriol


Assuming you're using an eval-based implementation, you could create an iframe to create a separate execution context. You could then use its global eval function to evaluate expressions in an isolated execution context. The context will preserve state between evaluations.

var iframe = document.createElement('iframe');

// We have to attach the iframe to the document to get a new execution context.
document.body.appendChild(iframe);

// Now the console implementation is simply the context's eval function.
var myConsole = iframe.contentWindow.eval;

myConsole('function SomeCustomFunction() { return "the result"; }');
myConsole('var x = SomeCustomFunction()'); // "the result"
myConsole('x.slice(4)'); // "result"
like image 39
Noah Freitas Avatar answered Oct 28 '22 01:10

Noah Freitas


I know this isn't exactly what you asked for.

You can develop a Google Chrome Extension using the devtools.inspectedWindow API https://developer.chrome.com/extensions/api_index#stable_apis.

"Use the chrome.devtools.inspectedWindow API to interact with the inspected window: obtain the tab ID for the inspected page, evaluate the code in the context of the inspected window, reload the page, or obtain the list of resources within the page."

Your scope is bound to the page.

like image 23
cbayram Avatar answered Oct 28 '22 02:10

cbayram