2

Is there a way to search for a JavaScript attribute (e.g. a named function) in the currently live object model (what Firebug displays on the 'DOM' tab, I couldn't find a direct equivalent in the Chrome Developer Tools) of the currently loaded page, using the common developer tools of the main browsers?

An example would be that I search for 'beta' and the developer tools show me something like window.alpha.beta, meaning that some script file has created an object named 'alpha' on the window object, which has an attribute beta.

I explicitly do not want to search for strings in all script files (e.g. Ctrl-Shift-F in the Chrome Developer Tools).

The use case is that I want to call a function of the page from an extension/userscript. I know the function exists, but it is created using a complex framework and I can't tell where in the page's object model it ends up.

PS: Terminology-related edits of the question are welcome.

Henrik Heimbuerger
  • 9,924
  • 6
  • 56
  • 69
  • 1
    If nobody provides a native answer, consider a recursive `for..in` search starting with `window` (and skipping `window.window` / `current === child`). – Paul S. Sep 15 '12 at 14:33
  • 1
    http://stackoverflow.com/questions/9828876/find-javascript-function-definition-in-chrome – Matt Whipple Sep 15 '12 at 14:34
  • @MattWhipple That's exactly the opposite case that I'm *not* interested in. I do have the function definition in front of me on the Resources tab in the Chrome Development Tools. The problem is that I don't know where it ends up on the page's object model after the code is executed. – Henrik Heimbuerger Sep 15 '12 at 14:36
  • 1
    If you click on elements tab in developer tools, you can click on any element and on right panel, you can click on properties and you can open first element to see all objects/properties associated with the selected element. In order to explore window object, you can go in Sources tab and add a watch expression for "window" and it will let you explore all global objects and functions as well. Have you checked this? – Akash Kava Sep 15 '12 at 14:40
  • @AkashKava Yes, thanks, that goes in the right direction. Unfortunately, there's a lot of those functions (2 MiB of minified JS) and they are in a complex object model, so manual 'browsing' of the tree is at worst hopeless and at best time intensive. That's why I was looking for a way to search through it (because I *do* know the name of the attribute, just not where it is). – Henrik Heimbuerger Sep 15 '12 at 14:51

4 Answers4

3

Loading https://github.com/angus-c/waldo and using it from the console looks like it should do the trick. A little more complex but also tool-agnostic.

Matt Whipple
  • 7,034
  • 1
  • 23
  • 34
  • Thanks, that looks excellent and seems to do exactly what I'm looking for on every other page. Unfortunately, it doesn't work on the page I need it on… Investigating now. – Henrik Heimbuerger Sep 15 '12 at 14:59
  • If you posted the function maybe we could be of more help. Right now it sounds like your the function you want is not available via the object model. It may be a closure. @hheimbuerger – Makaze Dec 17 '14 at 02:46
  • @Makaze I don't know the function! Exactly that was the use case: I'm trying to find its definition! If I knew what the function looked like, I wouldn't have a problem anymore. The use case was that I see a working function call (let's say `myfunc()`) and I want to know where in the object model the function lives (the answer might be something like `window.someobj.myfunc`, but that's exactly what I was trying to figure out). Assume the codebase to be some obfuscated framework, e.g. the Twitter or Facebook feeds. – Henrik Heimbuerger Dec 17 '14 at 09:43
  • I see. There are a few possible reasons why the Waldo solution wouldn't work, I think. 1.) The function in question is anonymous. I think that could be it, but correct me if I'm wrong. It's possible it is redefined every time it is run. 2.) The function is not a part of the object model (it is a normal variable closure within another function). 3.) The function is not being called from the window you are checking (perhaps it's within an iframe?). In that case it might be possible to access the function by applying Waldo's code to the iframe's global scope as well. – Makaze Dec 18 '14 at 10:29
1

I wrote up the recursive type function I mentioned in the comment as an anonymous function

(function(searchTerm, parent, parentStr, depthLeft, parentsArr){
    var p = parent || window,
        child, cObj = null,
        s = parentStr || '',
        r = [],
        d = (depthLeft > 0 ? depthLeft-1 : 5),
        pArr = parentsArr || [p];
    for( child in p ){
        cObj = p[child];
        if ( child === searchTerm ) r[ r.length ] = (s+'.'+child).slice(1);
        if( d > 0 && cObj !== null && p.hasOwnProperty(child) && typeof cObj === 'object' && cObj !== p && pArr.indexOf(cObj) === -1 )
            r = r.concat( arguments.callee( searchTerm, cObj, s+'.'+child, d, pArr.concat([cObj]) ) );
    }
    return r;
})('createElement');

Last line means will search for .createElement, starting from window. The deeper you go, the longer it will take.

Paul S.
  • 64,864
  • 9
  • 122
  • 138
  • You may need to try/catch around `cObj = p[child];` and do `cObj = null` in the catch to avoid `TypeError`s – Paul S. Sep 15 '12 at 16:02
0

If the function is global, you can call it from a userscript using this constructor:

var global = new Global(); // Initialize the Global constructor
// Some code
var globalVar = global.get('variableName'); // Assign the global variable 'variableName' to the local variable 'globalVar'

Because closures cannot be called from the global scope, you will have to use string searching to get any of those (as far as I know).

Makaze
  • 1,076
  • 7
  • 13
-1

The only way I can think of is by parsing your scripts and using regular expressions to avoid strings and other cases you may not want.

ngonzalvez
  • 431
  • 2
  • 10
  • That does not tell me where in the object model the function ends up. Again, I do have the source code of the function in front of me. I'm looking for the point in the DOM it gets loaded into. – Henrik Heimbuerger Sep 15 '12 at 14:37
  • 1
    So, what kind of return you want to get? A piece of code, a DOM element, or what? – ngonzalvez Sep 15 '12 at 14:43
  • The object model 'path' to the attribute, for example. See the example mentioned in the question, there it would be `window.alpha.beta`. Or the object popping up and being highlighted somewhere in the developer tool UI would be fine, too. – Henrik Heimbuerger Sep 15 '12 at 14:58
  • I missunderstood your question. I thought you were looking for a piece of script, that's why I told you that. – ngonzalvez Sep 15 '12 at 15:10
  • And because I expected people to misread my question, I explicitly stated that I'm not looking for a piece of script in the question. ;) – Henrik Heimbuerger Sep 15 '12 at 15:11