Development Blog

Internals: FirebugChrome

I’m working to create a functional test for Firebug’s Open-In-New-Window feature and then to get the feature to work again. In the process I think I’ve finally decoded how this feature works.

Here is the critical bit: Every Firebug window has a different copy of FirebugChrome, but they all share the same copy of the Firebug and FBL objects.

If you’ve looked through the Firebug source you should be familiar with the modules (controllers) and panels (views). You will also know the ubiquitous Firebug global object that holds everything together, the ‘context’ for each web page, and the utility code like lib.js and domplate.js.

You will also have encountered FirebugChrome, but (if you are like me) its role seems a bit puzzling. It seems to be most–but curiously not all–of global UI related code. Now that I am deep into the open in new window feature, I can understand: it holds just the code to run the Firebug window UI, whether that UI is in the browser or in a separate window.

When you open Firebug in a new window you already have one copy of FirebugChrome in the Firefox window. This object manages the various bit of the Firebug ‘chrome‘: the XUL overlays (browserOverlay.js and firebugOverlay.js), the XBL (bindings.xml), and all of the CSS. In the scope of the new Firebug window, a newly created FirebugChrome manages the chrome in the window. This window is of course not Firefox (browser.xul) but simple window defined in firebug.xul.

That is not so surprising, but the next step is: immediately the newly created FirebugChrome sets the global Firebug and FBL objects to point back into the original Firefox window. So all of the modules, panels, reps, and the context management code in Firebug are shared across the windows, but the FirebugChrome is unique to each window. This is how Firebug can ‘detach’ and ‘reattach’ to the browser: the metadata is shared and never has to moved or synchronized between windows. (This is also why you almost never see window global object used in Firebug).

One function shows the special role of FirebugChrome more than any other: setFirebugContext(context). This function (renamed in v1.4 from showContext()) simply sets the global FirebugContext object to the argument context. Beneath the simplicity lies the clues to how Open-In-New-Window works. Consider the call from a Firebug method:;

Here browser is essentially Firefox tab. Hanging off the tab is a reference, chrome, to the FirebugChrome object managing the Firebug window for the tab. If Firebug is open in Firefox, then chrome points to FirebugChrome in Firefox. But if Firebug is open in a new window, chrome points to a different FirebugChrome, the one managing the firebug.xul window. So when we execute setFirebugContext() we cross from the global object Firebug into the window-specific object FirebugChrome and then we set a global object, FirebugContext to one of the context objects. That’s how we get two different values for FirebugContext, one in Firefox and one the new Firebug window. Got it?


2 Responses to “Internals: FirebugChrome”

  1. Colin Barrett Says:

    Is it really necessary for every single mention of firebug to be in bold orange text?

  2. anon Says:

    Wow, that’s annoying. The boy who cried <strong/>?