I'm Aza Raskin @azaaza. I make shiny things. I simplify.

I'm the Creative Lead for Firefox.

 

What If… It Was Easy To Write Firefox Extensions

Sponsored by

Writing extensions is labor intensive. Even as a veteran web developer, I feel trepidation at the thought of diving into the boiler-plate code, wading through the XUL world, and restarting Firefox uncountable times. There are tools out there to mitigate some of these problems—like Ted Mielczarek’s Extension Wizard, and Mark Finkle’s FUEL—but they feel like fresh frosting on a stale, left-out-since-last-Thursday birthday cake.

Developer extroadinare, Atul Varma, said it best: “I hereby classify restarting Firefox during development as a ‘barbaric measure’”. Of course, restarting Firefox to install extensions is like-wise barbaric.

As a simple learn-to-write-extensions project, I decided to make a Gmail notifier. All I want it to do is and notify me—in a humane way—when a new email came in. As I dug into the the extension world, I found myself day-dreaming: What incredible places could the web go, as an open platform, if extending the web was as easy as writing for the web? What if my knowledge as a web developer was all I needed to extend Firefox? What if writing a Gmail notifier was as easy as:

function gmailNotifier() {
  var url = "http://mail.google.com/mail/feed/atom";

  ajaxGet(url, function(rss) {
    var firstEntry = $(rss).find("entry").get(0);

    var newEmailId = $(firstEntry).find("id").text();
    var subject    = $(firstEntry).find("title").text();
    var author     = $(firstEntry).find("author name").text();
    var summary    = $(firstEntry).find("summary").text();

    if( newEmailId != globals.lastEmailId ) {
      var title = author + ' says "' + subject + '"';
      displayMessage(summary, title);
    }

    globals.lastEmailId = newEmailId;
  });
}

function onStartup() {
  globals.lastEmailId = null;
  setInterval( gmailNotifier, 15*1000 );
}

Well, it isn’t that easy. Yet. *wink*

RT @azaaza What If… It Was Easy To Write Firefox Extensions | Follow @azaaza on Twitter | All blog posts

View all 23 comments


If it were easy, then I’d be out of a job – knock that talk off! :-)



skierpage

Is it possible to use the firefox -app trick to start a new XULRunner instance of Firefox (or a browser “lite”) while leaving your regular browser, and much of the shared library code, in memory? That would save some start-up time and loss of context. (I’d love to be able to do it to quickly test bugs against an empty profile.)



Kelly

I am filled with hope :-)



Byron

Hmmm interesting, especially liked the birthday cake analogy :D

It would be nice if Mozilla didn’t require its entire chrome to be reloaded in order to register another package.

going slightly off-topic here:
I couldn’t help noticing your use of jQuery in the example, whats the general practice for including JavaScript libraries? do many developers do it? if so what would be the best way? I know jquery already provides some help in this area but Im still not sure what would be considered best practice in this case.



rpgfan3233

On 2008-05-23 at 8pm, skierpage wrote:
> Is it possible to use the firefox -app trick to start a new
> XULRunner instance of Firefox (or a browser “lite”)
> while leaving your regular browser, and much of the
> shared library code, in memory? That would save some
> start-up time and loss of context. (I’d love to be able to
> do it to quickly test bugs against an empty profile.)

I’m not sure if it is possible, but I know you can have two different Firefox instances of different profiles using the -no-remote flag:

#Start a new Firefox instance using the profile name
# ‘Default’ without affecting a currently running profile.
#
#Note that you can’t run the same profile concurrently
# even with this trick.
firefox -no-remote -P “Default”



Ryan Paul

It’s a pity that bug 336551 makes E4X unusable for this sort of thing, because it would be way better than something like $(rss).find. If you scrub the XML so that Firefox’s E4X implementation can parse it, you could do something like this:

function displayData(rss) {
for each (var entry in rss..item) {
displayMessage(entry.summary, entry.author.name + ‘ says “‘ + entry.title + ‘”‘);
}
}

function loadcontent() {
var url = new XMLHttpRequest();
url.open(“GET”, “http://blah.com/somefeed.xml”, true);

url.onreadystatechange = function(e) {
if (url.readyState == 4) {
displayData(XML(url.responseText));
}
}

url.send(null);
}


Steve Yegge has an interesting post on extension systems that’s worth the (long) read, and he mentions Firefox’s explicitly (he’s, uh, not full of praise either).

http://steve-yegge.blogspot.com/2007/01/pinocchio-problem.html

I think we don’t see just how bad Firefox’s is since it’s still the best browser extension mechanism out there. That leaves us open to someone else doing it much better though, and if our extension system is a large part of what has made Firefox popular, that’s a worry. We don’t really want to be leapfrogged in this regard by IE.

Of course, as Steve mentions, writing a really good extension mechanism is also really, really hard.



Aza Raskin

@Ryan: I had no idea that EX4 existed. Thanks for the pointer.

@Byron: That’s a great question, and I’m not really sure of the answer. In Labs, we’ve decided that pragmatism should win out—so if including jQuery makes life easier, we’ll just do it.

@Jonathan: That’s exactly right. Once you’ve invested the significant amount of time to learn how to write extensions, you can no longer see the forest through the trees. I think a low tolerance for pain is critical when designing systems for other people. Also, thanks for the link. It’s epic!


It’s almost that simple if you use Greasemonkey. You won’t get a real extension that can utilize all of Firefox’s power but you will be able to do easy small customizations that’s if I remember correctly unfortunately are limited to the loading of individual pages and therefor can’t do any global customizations.

In some situations it can’t be used for easy extension of Firefox though and it shows how Fiefox’s real extensions could be improved.

Some Greasemonkey-scripts has also been reworked into real extensions making Greasemonkey a fast and easy testing ground for extension concepts.



skierpage

Thanks rpgfan, -no-remote -P works well and seems to start up very quickly when your main “firefox.exe” is running. I added a menu shortcut for it named “Minefield 2nd profile (-no-remote + profile)”

The trick should be promoted more, both for development and for reproducing bugs in a clean profile.



Aza

@skierpage: You should think about turning that into an extension itself ;)

@Pelle: Yep. Greasemonkey is a good first step. Too bad it is limited to acting only on page loads.


We definitely have a *lot* of boilerplate involved in writing extensions. Reducing the need for some of that would be great for the future. I think the main reason that it’s hard to simplify extension development is that extensions are essentially treated as additional chrome, handled just like the rest of the browser’s UI. While this gives you a lot of power, it also makes it very hard to do things like install without restarting, as there’s no real separation of the extension and application code in the internal representation. It might make sense to develop a more structured interface between extensions and the application, so we could do things in a more controlled manner. It’s sort of a trade-off, since the more defined you make the interface, the more restrictive it becomes.


Restarting an application during development is a common practice in many areas of software development (example: not all java application servers support hot deployment of code, and even the ones that do can be extremely flaky, resulting in frequent app server restarts).

That’s not to say restarts aren’t barbaric, but it is a common theme. It’s not a barrier-to-entry in terms of understanding and comprehension; it’s merely an inconvenience.

We should instead focus on simplifying other areas of extension development that result in less need for specialized domain knowledge (FUEL is a great start). Fixing development inconveniences like application restarts — which many software developers are already accustomed to because of other programming environments — will do nothing to reduce the current learning curve required to write one’s first extension.



Aza Raskin

@Eric: I’m not sure if that holds for web-developers. We aren’t used to long compile-time development practices. They aren’t just inconvenient—they fundamentally change the fast modify-reload dev cycle. That said, I think you are right about needing to also focus on other areas that result in less need for specialized domain knowledge.


This is not an outright solution, but in firefox one can set a couple of aprameters in the about:config page. When I do my extensions, it is only a matter of opening a new browser window and the changes to your extension sources kick in.

Also this relies on you having a link from .mozilla/firefox/extensions/plugins/ to the real source folder of your but its a one of thing for development.

Sorry I cannot recall the actual variables to be set, but these are documented in the firefox extension development documentation page.

Cheers
S


If FF did something like this, it would virally reinvent the web. Especially if that same power could work through prism on the desktop to trigger things not conventially thought of controllable via web scripting. I’m an old school Amiga guy, and I remember when just about anything could be scripted with AREXX.


It’s almost that simple if you use Greasemonkey. You won’t get a real extension that can utilize all of Firefox’s power but you will be able to do easy small customizations that’s if I remember correctly unfortunately are limited to the loading of individual pages and therefor can’t do any global customizations.


Leave a Comment