Thursday, December 31, 2009

Identifying from where JavaScript libraries invoke your callback functions, with Firebug

There comes a time where one would need to dig beyond the abstractions to see what is really going on under the covers.

Say for example you wanted to see how a certain library computes parameters for your callback, how would you do it? Scanning the library and figuring out the logic step by step is one way you can do it, but that is very time consuming and with complex libraries such as jQuery, it's nearly impossible to exactly pinpoint from where your callback function is being invoked.

In this post we will see how we can use Firebug to pinpoint exactly from where your callback functions are called in the abstraction.

A simple library

Let's take an example with a very small hypothetical "library" example:

var alibrary = (function () {
    var callback, 
    privatefun = function (p) {
        callback(p);
    }; 

    return {
        setCallback: function (fn) {
            callback = fn;
        },
        doIt: function () {
            var params = ['some', 'parameters', 22 + 20];
            privatefun(params);
        }
   };
}());

This 'library' offers 2 public functions; setCallback, which takes a function and stores it into the callback parameter and the doIt function that invokes the function that was stored previously.

Here's how this library can be used:

alibrary.setCallback(function (p) {
    console.log(p);
});

alibrary.doIt();


When the doIt function is called, the callback function that was passed previously will be invoked, passing in some parameters from behind. The library is passing an array as a parameter and the third element of that array is a computation of 22 + 20.

Now, as users of the library, we want to check how that 42 is computed from our callback function; and we will do this with Mozilla Firefox's best friend, Firebug

Tracing the steps

Open your Firebug (F12) and head onto the Script tab and choose the script from where you are defining your callback function. Then find your function and put a breakpoint in the function:



To set a breakpoint, click next to the line number in the and a red dot will appear.

The next step is to perform the action that will invoke your callback, and in my case this 'action' is a page refresh.

So now after my page refresh, the library will invoke my callback and the breakpoint will be hit:



When the breakpoint is hit, the line will be highlighted in yellow.

Now comes the part where we trace the steps back to where the callback was invoked. If you look closely to the upper part of the Script tab, you will see the following:



From there, you can now trace the path to where the function was invoked! Now let's click on the first step, privatefun().




Upon clicking, Firebug takes you directly to that function, privatefun, and now from this function we can see how our callback function was invoked:



Now although we can see from there the function was invoked, we still don't know from where that 42 is coming from, and so we must check which function invoked privatefun and to do that, we move a step back through the invocation line, the doIt() step:





From here, we can now see how that 42 was being computed because we have finally arrived to the step we wanted to.



Now obviously this technique isn't that much useful for this example because the code of this 'library' is so small that it doesn't require backtracking of the function calls, but it can be used very effectively on much larger libraries to quickly identify how certain parameters are being computed and sent to your functions, amongst other uses.