Firebug 1.10 Extension Architecture

From FirebugWiki

(Difference between revisions)
Jump to: navigation, search
Line 1: Line 1:
Firebug 1.10 introduces support for bootstrapped extensions and also new APIs for extensions. This page is intended to document these new APIs.
Firebug 1.10 introduces support for bootstrapped extensions and also new APIs for extensions. This page is intended to document these new APIs.
-
== Concepts ==
+
== Introduction ==
Firebug 1.10 supports three concepts that can be used when developing an extension:
Firebug 1.10 supports three concepts that can be used when developing an extension:
Line 9: Line 9:
-
=== XUL Based Extensions ===
+
== XUL Based Extensions ==
XUL represents an old school technique and Firebug has always supported this ways of extending. The main difference from the bootstrapped extensions is that you need to restart the browser whenever your extension is installed or uninstalled.
XUL represents an old school technique and Firebug has always supported this ways of extending. The main difference from the bootstrapped extensions is that you need to restart the browser whenever your extension is installed or uninstalled.
Line 29: Line 29:
-
=== Bootstrapped Extensions ===
+
== Bootstrapped Extensions ==
Support for bootstrapped extensions has been introduced in Firebug 1.10. There are (at least) three entities you'll be dealing with when developing basic structure of a bootstrapped (restart-less) extension.
Support for bootstrapped extensions has been introduced in Firebug 1.10. There are (at least) three entities you'll be dealing with when developing basic structure of a bootstrapped (restart-less) extension.
-
* bootstrap.js - Every Firefox bootstrapped extension needs to provide a '''bootstrap.js''' file that is expected to implement basic functions like: '''install''', '''uninstall''', '''startup''', '''shutdown'''. In case of a Firebug extension further functions like: '''firebugStartup''', '''firebugFrameLoad''', etc. are expected. These functions/callbacks are automatically executed to allow proper initialization/shutdown of the extension.
+
* <code>bootstrap.js</code> - Every Firefox bootstrapped extension needs to provide a '''bootstrap.js''' file that is expected to implement basic functions like: '''install''', '''uninstall''', '''startup''', '''shutdown'''. In case of a Firebug extension further functions like: '''firebugStartup''', '''firebugFrameLoad''', etc. are expected. These functions/callbacks are automatically executed to allow proper initialization/shutdown of the extension.
-
* FirebugLoader - is a component <code>resource://firebug/loader.js</code> that distributes events to all Firebug bootstrapped extensions.
+
* <code>FirebugLoader</code> - is a component <code>resource://firebug/loader.js</code> that distributes events to all Firebug bootstrapped extensions.
-
* Firebug - The Firebug object  
+
* <code>Firebug</code> - The Firebug object  
See following sequence diagram:
See following sequence diagram:
Line 51: Line 51:
Following Firebug related callbacks can be implemented in bootstrap.js file:
Following Firebug related callbacks can be implemented in bootstrap.js file:
-
* firebugStartup() - called when Firebug is bootstrapped
+
* <code>firebugStartup()</code> - called when Firebug is bootstrapped
-
* firebugShutdown() - called when Firebug is uninstalled
+
* <code>firebugShutdown()</code> - called when Firebug is uninstalled
-
* topWindowLoad(win) - called when a new browser window is opened
+
* <code>topWindowLoad(win)</code> - called when a new browser window is opened
-
* topWindowUnload(win) - called when an existing browser window is closed
+
* <code>topWindowUnload(win)</code> - called when an existing browser window is closed
-
* firebugFrameLoad(Firebug) - called when Firebug UI is loaded into an existing browser window
+
* <code>firebugFrameLoad(Firebug)</code> - called when Firebug UI is loaded into an existing browser window
-
* firebugFrameUnload(Firebug) - called when Firebug UI is unloaded from an existing browser window
+
* <code>firebugFrameUnload(Firebug)</code> - called when Firebug UI is unloaded from an existing browser window
Line 62: Line 62:
-
=== AMD Extensions ===
+
== AMD Extensions ==
-
This technique (Asynchronous Module Definition) is related to how code of your extension is organized. It can be used together with XUL based or bootstrapped extensions. Using AMD in your extension is recommended since it helps to organizes your code into modules, properly maintain dependencies and use external modules such as those provided by Firebug framework.
+
This technique (Asynchronous Module Definition) is related to how code of your extension is organized. It can be used together with XUL based or bootstrapped extensions. Using AMD in your extension is recommended since it helps to organize your code into modules, properly maintain dependencies and use external modules such as those provided by Firebug framework.
-
TODO
+
Typical example of a Firebug module can as follows:
 +
 
 +
<source lang="javascript">
 +
define([
 +
    "firebug/lib/trace"
 +
],
 +
function (FBTrace) {
 +
 
 +
var myModuleObject =
 +
{
 +
    myFunction: function()
 +
    {
 +
        FBTrace.sysout("My function executed!");
 +
    }
 +
}
 +
 
 +
return myModuleObject;
 +
});
 +
</source>
 +
 
 +
* The module specifies one dependency: '''firebug/lib/trace''' modules (Firebug tracing)
 +
* The module implement one object with one function that is also returned from the module
 +
* See more about [http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition AMD] syntax.
 +
 
 +
Extensions based on AMD can use Firebug's built-in module loader and also APIs that automatically load entire extension.
 +
 
 +
 
 +
=== AMD & XUL Overlay ===
 +
First see how to register our AMD based extension from a XUL overlay.
 +
 
 +
An overlay applied to <code>chrome://firebug/content/firebugOverlay.xul</code>
 +
 
 +
<pre>
 +
<?xml version="1.0"?>
 +
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 +
    <script type="application/x-javascript" src="firebugOverlay.js"/>
 +
</overlay>
 +
</pre>
 +
 
 +
The '''firebugOverlay.js''' represents extension's entry point.
 +
 
 +
<source lang="javascript">
 +
var config = {id: "helloworld@janodvarko.cz"};
 +
Firebug.registerExtension("helloworld", config);
 +
</source>
 +
 
 +
* The extension registers itself within Firebug framework
 +
* The extension uses an ID coming from '''install.rdf'''
 +
* The registration will automatically look for '''main''' module and load it
 +
 
 +
 
 +
=== Bootstrap & AMD ===
 +
In case of bootstrapped extension the entry point isn't a XUL overlay, but '''bootstrap.js''' file. Again we need to make sure that '''Firebug.registerExtension''' is called. See the following shortened example:
 +
 
 +
<source lang="javascript">
 +
function firebugFrameLoad(Firebug)
 +
{
 +
    var config = {id: "helloworld@janodvarko.cz"};
 +
    Firebug.registerExtension("helloworld", config);
 +
}
 +
 
 +
function firebugFrameUnload(Firebug)
 +
{
 +
    if (!Firebug.isInitialized)
 +
        return;
 +
 
 +
    Firebug.unregisterExtension("hellobootamd");
 +
}
 +
</source>
 +
 
 +
* '''firebugFrameLoaded''' is called when an instance of Firebug is loaded (happens when the user opens Firebug for the first time). There is one instance of Firebug per browser window.
 +
* Again, we are using ID coming from '''install.rdf'''
 +
* Since, it's bootstrapped extension we need to also handle uninstall and disable so, unregister the extension in these cases.
 +
* The registration will automatically look for '''main''' module and load it
 +
 
 +
 
 +
=== Main Module ===
 +
As soon as the extension is registered, Firebug is looking for '''main''' module and loads it. Here is an example of such module.

Revision as of 13:01, 10 February 2012

Firebug 1.10 introduces support for bootstrapped extensions and also new APIs for extensions. This page is intended to document these new APIs.

Contents

Introduction

Firebug 1.10 supports three concepts that can be used when developing an extension:

  • XUL Based Extensions
  • Bootstrapped Extensions
  • AMD Extensions


XUL Based Extensions

XUL represents an old school technique and Firebug has always supported this ways of extending. The main difference from the bootstrapped extensions is that you need to restart the browser whenever your extension is installed or uninstalled.

Important thing related to XUL based extension is to understand scopes. First see the next diagram.

Firebug-scopes.png

There are two scopes that are relevant to extension development.

  • Browser Window: use this scope when overlaying browser UI. Your extension might want to append new button into Firefox toolbar or create, create a new menu items, etc.
  • Firebug UI: this is the scope mostly used by Firebug extension, use it whenever you want to extend Firebug. Your extension might want to crate a new Firebug panel, etc.

Note that Firebug 1.10 introduces a new feature called Delayed Load. This means that overlays applied to chrome://firebug/content/firebugOverlay.xul are loaded the first time the Firebug UI is actually opened by the user. This way loading doesn't slow down Firefox start up time.

Also, the global Firebug object is available since Firefox start even if Firebug is not fully loaded yet, but contains only a small set of APIs.


Bootstrapped Extensions

Support for bootstrapped extensions has been introduced in Firebug 1.10. There are (at least) three entities you'll be dealing with when developing basic structure of a bootstrapped (restart-less) extension.

  • bootstrap.js - Every Firefox bootstrapped extension needs to provide a bootstrap.js file that is expected to implement basic functions like: install, uninstall, startup, shutdown. In case of a Firebug extension further functions like: firebugStartup, firebugFrameLoad, etc. are expected. These functions/callbacks are automatically executed to allow proper initialization/shutdown of the extension.
  • FirebugLoader - is a component resource://firebug/loader.js that distributes events to all Firebug bootstrapped extensions.
  • Firebug - The Firebug object

See following sequence diagram:

Bootstrapped-init.png

  • When Firebug itself is loaded (bootstrapped), FirebugLoader fires an firebugStartup event. This is the moment when the extension can register itself as a listener for further events by calling registerBootstrappScope function.
  • Later when the user requires Firebug for the first time, the firebugFrameLoad callback is executed. The callback has one parameter the Firebug object. This is also the time when overlays applied to chrome://firebug/content/firebugOverlay.xul are loaded.
  • If the extension is using AMD, it can register itself as by calling Firebug.registerExtension (see further AMD Extensions chapter)


Following Firebug related callbacks can be implemented in bootstrap.js file:

  • firebugStartup() - called when Firebug is bootstrapped
  • firebugShutdown() - called when Firebug is uninstalled
  • topWindowLoad(win) - called when a new browser window is opened
  • topWindowUnload(win) - called when an existing browser window is closed
  • firebugFrameLoad(Firebug) - called when Firebug UI is loaded into an existing browser window
  • firebugFrameUnload(Firebug) - called when Firebug UI is unloaded from an existing browser window


An example of bootstrapped Firebug extension is available.


AMD Extensions

This technique (Asynchronous Module Definition) is related to how code of your extension is organized. It can be used together with XUL based or bootstrapped extensions. Using AMD in your extension is recommended since it helps to organize your code into modules, properly maintain dependencies and use external modules such as those provided by Firebug framework.

Typical example of a Firebug module can as follows:

define([
    "firebug/lib/trace"
],
function (FBTrace) {
 
var myModuleObject =
{
    myFunction: function()
    {
        FBTrace.sysout("My function executed!");
    }
}
 
return myModuleObject;
});
  • The module specifies one dependency: firebug/lib/trace modules (Firebug tracing)
  • The module implement one object with one function that is also returned from the module
  • See more about AMD syntax.

Extensions based on AMD can use Firebug's built-in module loader and also APIs that automatically load entire extension.


AMD & XUL Overlay

First see how to register our AMD based extension from a XUL overlay.

An overlay applied to chrome://firebug/content/firebugOverlay.xul

<?xml version="1.0"?>
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    <script type="application/x-javascript" src="firebugOverlay.js"/>
</overlay>

The firebugOverlay.js represents extension's entry point.

var config = {id: "helloworld@janodvarko.cz"};
Firebug.registerExtension("helloworld", config);
  • The extension registers itself within Firebug framework
  • The extension uses an ID coming from install.rdf
  • The registration will automatically look for main module and load it


Bootstrap & AMD

In case of bootstrapped extension the entry point isn't a XUL overlay, but bootstrap.js file. Again we need to make sure that Firebug.registerExtension is called. See the following shortened example:

function firebugFrameLoad(Firebug)
{
    var config = {id: "helloworld@janodvarko.cz"};
    Firebug.registerExtension("helloworld", config);
}
 
function firebugFrameUnload(Firebug)
{
    if (!Firebug.isInitialized)
        return;
 
    Firebug.unregisterExtension("hellobootamd");
}
  • firebugFrameLoaded is called when an instance of Firebug is loaded (happens when the user opens Firebug for the first time). There is one instance of Firebug per browser window.
  • Again, we are using ID coming from install.rdf
  • Since, it's bootstrapped extension we need to also handle uninstall and disable so, unregister the extension in these cases.
  • The registration will automatically look for main module and load it


Main Module

As soon as the extension is registered, Firebug is looking for main module and loads it. Here is an example of such module.

Personal tools