See also Firebug 1.4 activation model.

One of the most noticeable thing (apart from bunch of bug-fixes) of the upcoming Firebug 1.2beta4 (check AMO) is new UI for Firebug activation.

We have been hardworking on this (UI is hard), following carefully all the great user feedback on Firebug newsgroups, and this version has finally something, which looks like quite promising solution (I am curious about the next user feedback ;-).

In the previous version (Firebug 1.05 and 1.1), it was only possible to disabled/enable Firebug entirely (and/or for specific site). However, most of the Firebug features don't reduce Firefox performance and thus can be available and handy all the time. For instance, the DOM Inspector is indispensable tool for a lot of users and there is no performance penalty when using Firefox.

The solution we have chosen makes possible to independently enable/disable those features that can reduce Firefox performance (now disabled by default). The other features are just available and there is no reason to disable them.

So, the following panels are currently activable:

  • Console logging - Console panel
  • Javascript Debugger - Script panel
  • Network monitoring - Net panel

We have introduced a new menu, which is accessible directly from the panel's tab. See the following screen-shots. You can also notice that disabled tab label is grayed out (click the image to enlarge it).

Firebug activation menu

and...

Firebug activation menu

The menu is available for all activable panels (i.e. for those which can be enabled/disabled) and is displayed only for the currently selected tab so, the space on the tab-bar isn’t wasted. The menu target (the black-arrow) can’t be overlooked by the user, but it’s also not eye catching.

All the activable logic is behind these four options:

  1. Enabled – The panel is enabled for all sites.
  2. Disabled - The panel is disabled for all sites.
  3. Enable <panel>for <site> - The panel is enabled for specific site.
  4. Disable <panel> for <site> - The panel is enabled for specific site.

So, some users who use Firebug just occasionally can keep all activable panels disabled and perhaps enable them only for some specific sites. The others can enable all panels and perhaps disable them just for sites like e.g. gmail.

There is also additional Sites... option that displays list of sites for which the panel has been enabled or disabled.

List of enabled/disabled sites

You can see that in this case, Network Monitor has been enabled for www.google.cz.

Finally, the following page is displayed for a disabled panel (Net panel in this case). The page allows one click enablement of the panel and also activation of multiple panels at once. The user can just select appropriate panels and press Enable selected... button.

Firebug\'s panel disabled

The internal architecture of the UI is extensible so, possible Firebug extensions can utilize all the APIs and hook up into the UI as well. This will be useful especially for the user as the activation approach will be the same thorough entire Firebug IDE.

I welcome any new ideas about how to improve the UI!

Just a quick update for all who just installed fresh new Firefox 3 and want to use latest compatible Firecookie extension.

Download Firecookie 0.6

I would also strongly recommend to  use Firebug 1.2 with Firefox 3.

One of the most interesting parts of the Firebug framework is a template system called Domplate. This engine is used to generate HTML UI of Firebug (content of all FB's panels).

It's quite powerful template system and I would definitely recommend to use it when creating UI for Firebug extensions.

Domplate generates the result HTML markup according to templates written in JavaScript. These templates are internally evaluated into a text, which is consequently inserted into specified DOM element on the page through innerHTML property.

It's also possible to define DOM event listeners so, the template object can handle even the user interaction with the final UI.

Hello World! template

So, let's take a look at how to make up some HTML for our Hello World! extension. First of all, see the following piece of code that defines a simple Domplate template.

var helloWorldRep = domplate(
{
    myTag:
        DIV({class: "MyDiv"},
            "Hello World!"
        )
});

HTML generated from this template should look like as follows:

<DIV class="MyDiv">Hello World!</DIV>

The template object is created by domplate function and stored in helloWorldRep variable. This new object usually contains three type of properties:

  1. Tag - set of functions (constructors) that represent a markup template.
  2. Data provider - a function that is intended to provide dynamic data for the template during generation process.
  3. Event handler - a function that is intended to handle DOM events fired when the generated UI is used by the user.

In our case, we have only one tag that describes how the result markup should look like. Only static text will be generated so, no additional providers or handlers are necessary.

The next piece of code shows how to evaluate the template and append generated HTML into our panel. It's executed within onMyButton function, which is a handler for a toolbar button created in part II.

onMyButton: function(context)
{
    var panel = context.getPanel(panelName);
    var parentNode = panel.panelNode;
    var rootTemplateElement = helloWorldRep.myTag.append(
        {}, parentNode, helloWorldRep);
}

We are using panel's member variable panelNode, which represents content area of the panel - final HTML will be inserted into it. Notice that we are using getPanel function to get our panel for the current context (page) where panelName represents ID of the panel, see part II.

HTML is inserted into the panel by calling append method of the template tag. This method has three parameters. The first one is used to provide data for the template, it's just empty object in our case as there are no dynamic properties in our template. The second is the parent DOM node and the last represents context object (this) that contains callback methods (data providers and event handlers). It can be null in our case as we don't have any callbacks yet, but it's good practice to use the template itself. It's usually the template which defines all these callbacks. Return value is root element of the created DOM (we don't need it for now).

In order to test the example just press Say Hello toolbar button (multiple times). Following screenshot shows how the output should look like.

Dynamic template

Let's make our template a bit more complicated and see how to (a) use dynamic properties, (b) localize the message and (c) use an event listener.

var helloWorldRep = domplate(
{
    myTag:
        DIV({class: "MyDiv", onclick: "$onClick"},
            SPAN($HW_STR("helloworld.message")),
            SPAN(" "),
            SPAN("$date")
        ),

    onClick: function(event)
    {
        alert("Hello World!");
    }
});

The templates uses a dynamic property date so, don't forget to provide the actual value when inserting the template output into the page.

onMyButton: function(context)
{
    var panel = context.getPanel(panelName);
    var args = {
        date: (new Date()).toGMTString()
    };
    var root = helloWorldRep.myTag.append(args, panel.panelNode, null);
},

Generated markup should look as follows:

<DIV class="MyDiv">
    <SPAN>Hello World!</SPAN>
    <SPAN> </SPAN>
    <SPAN>Wed, 04 Jun 2008 11:06:28 GMT</SPAN>
</DIV>

$date represents an expression that looks for a property named date within provided args object. The onclick: "$onClick" statement looks for a method named onClick within the provided args object and if it's not there it looks within context object (the third parameter of the append method). Finally, the Hello World! message is localized using our $HW_STR method that comes from part IV.

Example extension (helloworld-0.0.5.xpi) can be downloaded here.

Domplate & JQuery

Entire engine is completely independent of the rest of Firebug API and so, it can be also easily used individually (e.g. within a web page). There is already some activity in this area. Christoph Dorn (creator of FirePHP) wrapped it into a jquery plugin. You can download it here.