views:

243

answers:

2

[1] Ok, I don't even know how to call this, to be honest. So let me get some semi-pseudo code, to show what I'm trying to do. I'm using jquery to get an already existing script declared inside the page, inside a createDocument() element, from an AJAX call.

GM_xmlhttprequest({
  ...
  load:function(r){
    var doc = document_from_string(r.responseText);
    script_content = $('body script:regex(html, local_xw_sig)', doc).html();
    var scriptEl = document.createElement('script');
    scriptEl.type = 'text/javascript';
    scriptEl.innerHTML = script_content; // good till here
    (function(sc){
      eval(sc.innerHTML); // not exactly like this, but you get the idea, errors
      alert('wont get here ' + local_xw_sig); // local_xw_sig is a global "var" inside the source
    })(scriptEl);
  }
});

so far so good, the script indeed contains the source from the entire script block. Now, inside this "script_content", there are auto executing functions, like $(document).ready(function(){...}) that, everything I "eval" the innerHTML, it executes this code, halting my encapsulated script. like variables that doesn't exist, etc

removing certain parts of the script using regex isn't really an option... what I really wanted is to "walk" inside the function. like do a (completely fictional):

script = eval("function(){" + script_content + "};");
alert(script['local_xw_sig']); // a03ucc34095cw3495

is there any way to 'disassemble' the function, and be able to reach the "var"s inside of it? like this function:

function hello(){
  var message = "hello";
}
alert(hello.message); // message = var inside the function

is it possible at all? or I will have to hack my way using regex? ;P

[2] also, is there any way I can access javascript inside a document created with "createDocument"?

A: 

Simply trying to access a local variable inside a function from outside of it is impossible due to scope. However, using closures you can absolutely accomplish this:

function hello(msg){
  return function message(){
    return msg;
  }
}
alert(hello("yourMessage")()); // will alert "yourMessage"

Note exactly what's happening here. You are calling a function which returns a function, in which "yourMessage" is now defined inside its scope. Calling that inner closure the second time will yield that variable you set earlier.

If you are not familiar with closures in JS, I suggest you read this wonderful FAQ.

Yuval A
I don't have access to the original script. It's a call from a Greasemonkey script. and since I'm receiving it as text inside "createDocument" (it doesn't execute javascript), I can transverse the script tags, but there isn't a way to get the variables inside without doing regex...
caesar2k
yeah, I'm familiar with closures. and I just had an idea, not sure if it will work. since I'm working basically on Firefox, I will try to encapsulate in an anonymous function, then call .toSource()/uneval I might be able to get the members with it (parsing again with JSON for example)
caesar2k
A: 

It's not possible that way. You can introspect object's properties (any function is an object), but not before you have created an instance with new operator.

Looking at your code sample, it seems that your approach is a bit messy – eval()'ing script blocks is something one should not do unless absolutely necessary (a situation I can't imagine).

jholster
unless the script functions or variables can be accessed through a document created with document.implementation.createDocument(), I need to use eval, no other way around
caesar2k