My Dream Way To Write A Firefox Extension
The add-ons community for Firefox is one of the largest, most vibrant sources for innovation in the browser. If you want to affect people, to reach them and make a difference in their daily lives, the Firefox extension platform is hard to beat, with over a billion downloads of Firefox add-ons in total.
I want to be able to participate in that community, but I find it difficult.
You see, I’m a Web development and not a software developer in the traditional sense. Things like compilers, linkers, and build steps are scary. I prefer the Web and how it allows real-time feedback and instant gratification. I prefer its super-low barrier to entry. I do web development because that’s where it’s possible for me to translate my thoughts into reality.
The thing is, there are hundreds of thousands of developers just like me.
They represent an amazing and untapped wealth of innovation, of vision towards the future user experiences of the web. Imagine if any 8th grader who can write a web page could fundamentally enhance the browser, or just make the web a better place for his/her Mom.
In addition to formal explorations that explore light-weight browser customization—Personas and Ubiquity—we’re talking with add-on developers now, and soon the wider development community, to explore potential improvements to the Firefox Add-ons system. These improvements wouldn’t replace the current Add-on method — instead they would add another approach more easily grokked by web developers. As Add-ons Lead Nick Nguyen recently said, “Mozilla is about choice”.
This is a sketch of how I’d like to be able to write a Firefox extension.
It’s a URL
There’s no build-step for writing most web pages. You just write the code, point your browser at it, and it goes, whether it’s local or remote. To include separate files or 3rd party libraries you just point to their URL. It’s light-weight and robust.
If to install an extension was to just give my browser a URL, I could easily use an cloud-based editor like Bespin to take care of all my dev needs, from version control, to concept, to distribution.
For development I want instant gratification with a minimum of fuss. It’s how developing and subscribing to Ubiquity commands work. The same, if not more so, should be true for add-ons.
The Code
Concise, easy, and webby is the goal. These are just sketches, and we’d love feedback and alternative dreams.
Let’s dive into some examples.
Weather Badge in the Navigation Bar
This add-on puts a button in the navigation bar that displays the current weather forecast. When clicked, it opens a page to more a more detailed weather forecast.
file: weather.ext
<extension>
<button id="weather" width="100px" height="100px"/>
<script id="init">
updateWeather(){
Utils.xhr({
url: "http://...",
callback: function( data ){
var weather = $("#weather");
weather.img = data.img;
weather.text = data.description;
}
});
}
$("#weather").click(function(){
window.open( "http://..." );
});
Browser.Windows.onload(function(){
Browser.UI.NavigationBar.add({
id: "weather"
});
updateWeather();
setInterval( updateWeather, 1000*60 );
});
</script>
</extension>
Clock in the Status Bar
Let’s take another example, this one split into two files. Say I wanted to add a digital clock to the status bar. This is how I want the extension to look:
file: init.js
Browser.Windows.onload( function(){
Browser.UI.StatusBar.add({
href: "status-clock.html";
});
});
file: status-clock.html
<html>
<head>
<style>
body{ height: 10px; width: 20px; background: transparent; color: black;}
</style>
</head>
<body>
<div id="time"></div>
<script>
// Update the time every second.
setInterval( function(){
jQuery("#time").text( Date().split(" ")[4] );
}, 10);
</script>
</body>
</html>
Tab Recover
One more. Let’s augment the new tab screen to show links to recently closed tabs, as well as add a context menu item that let’s you open a recently closed tab.
file: closed-tabs.ext
<extension>
<li id="menu-item">Open last closed tab</li>
<script id="init">
Browser.Windows.Tabs.onload(function( window ){
if( window.location != "about:blank" ) return;
/* Construct a list (li's) of recently closed tabs in HTML format. */
var recentTabs = ...;
$( "li", recentTabs).onclick(function()){
window.open( this.url );
});
$(window.document.body).append( recentTabs );
});
Browser.onload(function(){
Browser.UI.ContextMenu.add({
id: "menu-item",
onclick: function(){
/* Get the last closed tab. */
var lastClosedTab = ...
window.open( lastClosedTab.url );
}
});
});
</script>
</extension>
Debugging
I’d like to be able to open my extensions in a web page and debug them with Firebug. In the second example, because much of the code is outsourced to a HTML page, debugging it is as simple as pointing a browser at it.
For more complicated extensions, we can mock-out the Browser object so that the extensions can be prototyped in content-space.
Really, anything that gives line numbers and useful error messages would be a big help in debugging my mistakes.
Portable
Because everything is encapsulated in an API, the host user-agent gets to decide what extension points look and feel like. For instance, calling Browser.StatusBar.add() can do the correct (and different) thing on Firefox Mobile, Thunderbird, or Firefox proper.
Unit Tests
We need it, but I’m not sure what it should look like. Being “webby” means mixing business logic with display logic, which mixes unit tests with functional test. I’m not sure how to unravel the problem. Help!
Your Turn
These are my sketches and thoughts on how I’d like to be able to extend Firefox using my web-developer skill set. How would you like to be able to extend Firefox? What should the code look like? Let us know.
Blog posts with example code get extra brownie points — possibly in the form of the extra Firefox shirts sitting on my desk :)
RT @azaaza My Dream Way To Write A Firefox Extension | Follow @azaaza on Twitter | All blog posts
Tags: add-ons, extensions
Tristan
Totally agree with the need to lower the barrier to entry. What you write is totally in line with Mark Surman’s “Hackability” theme that was discussed at Fosdem and will demoed in the upcoming Utrecht Mozcamp. https://wiki.mozilla.org/MozCamp/Utrecht
Nitpicking: “I prefer it’s” -> “I prefer its”. Also “&mdash” -> “—”.
Aza Raskin
@Tristan Thanks for those nitpicks. (Aza hides in shame).
mikeal
In all the extensions that I have there is a “stdlib” directory next to my other “modules” directory for my resource.
This includes all the stuff that should be easy but isn’t, it’s an attempt to abstract a lot of the nastier more difficult tasks that I have to do over and over again. It’s kind of a larger version of the ubiquity utils.js module, in fact I’ve pulled my setTimeout code from that module (thanks!).
In my latest extension I’m starting to consolidate and clean up all these little bits so that I can later push it out as it’s own project. I agree that there are deeper problems that this won’t solve, but reading in a file shouldn’t be 8 lines of code, that’s just wrong.
FUEL was a noble attempt to clean this up but seems to be left only part of the way finished and I find it seems to lack consistent utility.
-Mikeal
mikeal
On a separate thread. I think we as a community can overcome most of these problems without work a lot of work happening inside of Firefox if the platform included a dependency declaration and management system.
Right now sharing code between extensions requires either dropping all the code you want in to your extension copied from another extension, or trying to require the user to install something else by hand before they install your extension (this is the process for all the current Firebug plugins).
We could do great unittest integration for extension developers via mozmill but we don’t have a smooth way to integrate a foreign extension in to their development workflow. We could create libraries that served as abstractions over all these warts but the extensions don’t have a facility to “depend” on them.
Aubrey
If this happened, it would change the face of web browsing. You would have a second army of rabid plugin developers, and I would march amongst them. There are a lot of people out there with great ideas that just are not willing to take the time to learn XUL and end up implementing stand-alone ideas on the web. If you make it easy to grow your own browser and share that experience with others, expect a revolution.
tobi
Aza, great that you care about this topic. I’m even less of a developer, I’m a designer, I care more about the Idea than about the code. My code gets messy, sometimes I just through away everything, and start using the Greasemonkey API instead. It’s awesome. If we want add-ons to become more mainstream, mozilla needs something like that. A layer above XUL, an API for power users like me, who know what they want, but don’t want to get lost in the nerdy docu all the time. This would be a good start: http://wiki.greasespot.net/API_reference .
hey Aza, I’m in Asa’s office this week. Hope to see at some point!! best, tobi
Tim
I think this is good. It seems like what you were trying to do with the new way to write Ubiquity commands, ( http://www.azarask.in/blog/post/a-new-way-of-writing-ubiquity-commands-feedback-needed/ ) but I think it will work much better for extensions than for Ubiquity commands. (in case my wording is confusing, I’m saying that writing Ubiquity commands as HTML/JS has too many issues and should be left the way it is, but writing extensions as HTML/JS is good)
Dan Cardin
If im understanding this correctly, then you’d be able to update extensions without having to restart the browser. Essentially extensions would turn into more integrated stylish, or greasemonkey scripts. amirite?
Chris
Fantastic. There’s still room for improvement though. Currently to alter Firefox you need to use overlays. You have used Browser.statusBar.add instead; another route is to simply use a version control system.
If the status bar itself was written in HTML, then all you would have to do is load the html up, make the relevant changes, then submit the patch back to Firefox as a version control diff. A tool like Bespin could handle all this for you; just load the browser chrome code, make changes, and submit the results back to the browser. There would be no need for non-standard statusbar.add commands.
If you think about it, overlays are just a way to get around not having version control on the client chrome code.
Laurentj
@chris : using html for the interface ? XUL is much much better for that ! We should keep XUL ! However, your idea about the way to propose patch is cool, and we can do it with XUL ;-)
@aza : this ideas of new kind of extension is very cool. But I hope Mozilla will keep the old extension system, to have the ability to create complex extensions.
Don’t forget also the “plateform”, don’t forget XulRunner. I think the use of the name “Browser” for the global object is a bad idea, because it has no sense in the context of Thunderbird, Songbird or else. You should call it “Application”, so the general API could be used also in other XUL applications
Application.Windows.onload(…)
Application.UI….
Application.UI.ContextMenu
Application.onload(…)
etc…
And browser specifics should be on an object like “Application.Browser”, or a global “Browser” object.
Chris
I agree with you that many extensions should register new URIs. This practice is sadly missing from most of Firefox. For example, what’s the URI for the history sidebar? Or the options dialog box? I think it should be about:history and about:options, respectively. It’s not easy or clear to find out right now. But writing these components as web pages with URIs would massively ease extension development.
I made a start on this in a forthcoming about:history extension (http://chrisfjay.blogspot.com/2009/01/announcing-abouthistory.html) currently awaiting approval in AMO.
MarkC
To some extent this is similar to using Remote XUL. At the moment Remote XUL seems to be the bastard stepchild of the XUL world, kept hidden under the stairs while browser chrome and extensions get all the limelight.
I can already point Firefox at the URL for a Remote XUL app and get a rich, powerful UI written with a very HTML-like syntax. The only step missing is to get it to render somewhere other than the main browser window. The security implications of that are another matter entirely, though.
FWIW, I do a lot of Remote XUL development and never have to go anywhere near a compiler, linker or builder. Compared with packaging up a Firefox extension, Remote XUL really is as simple as writing some XML and Javascript, then pointing the browser at the URL.
Neil
Actually, with minor modifications, your examples will work with the existing extension system. What you haven’t described is the hard part, which is doing all the preamble to ensure extra permisssions, indicating to the browser where the extension is located, as well as define information such as the name and description for use with the addons manager and addons.mozilla.org, not to mention actually getting it on the addons site. These are things that one has to do in some way or another anyway, so making the script syntax different (your proposed version by the way, is kind of verbose) doesn’t really give one a ‘no-build’ mechanism in reality.
Adam Buono
I really do wish that I could use web development skills everywhere. With desktop applications moving to the browser and vica-versa, the reality is that the web and it’s low barrier to entry is entering the software world.
Being primarily experienced in web, and the easy of use, half my tasks I do on my computer a little scripts thrown together. These scripts are doing what would traditionally be done by a piece of software, I instead run them out of my browser.
Is this just lazyness to learn a real software language in-depth, or are web languages going to make a bigger impact on actual software in the future. It sure would be fun to tweak Firefox without learning scary new syntax.
drewlesueur
I really liked the post.
Andrea
Can’t wait to see how Chrome extensions will work, I bet they will be so smart that will become a standard de-facto…
And perhaps will be similar to your proposal :-)
Clint
As far as unit testing extensions are concerned, this has been (and continues to be) one my primary motivations for Mozmill. I think it’s a simple enough framework to write tests in, and since it can automate and interact with both chrome and content, and since it has a built-in unit test API, I think it’s a good candidate for helping out with the testing side of this.
Stephen
I’m currently working on my 2nd Firefox extension and I would definitely agree with you on the significant barriers to entry there are in extension development. Things like packaging, how to keep your code from polluting the global namespace, overlays, and other things are confusing for first time developers to understand, and there isn’t any really good documentation on the Right Way. FUEL was definitely supposed to help, but currently things like file IO, tab notifications, and UI adjustments still often require extensive searching and use of XPCOM. However, both the extensions I wrote wouldn’t be possible without the use of XPCOM, so while it would be awesome to have a simpler API for the more commonly accomplished things, replacing XPCOM is probably out of the question.
Tim
Another cool thing about this method is that it could be implemented by other browsers so your add-ons are cross-browser. Maybe even have it as a W3C standard so that all standards-compliant browsers can take any such add-on! :)
Quickredfox
What’s wrong with using greasemonkey + the user script compiler (http://arantius.com/misc/greasemonkey/script-compiler)? I mean, you did say it’s the compiling and stuff that get complicated… how about edit-script-and-refresh-page? Coz that’s what you get with greasemonkey
Scott Fitchet
Aza … thanks for doing this. Would love to see your XUL notes from the last jQuery conference.
How would I get something like JSON feed data into this URL bar …. http://www.figital.com/xul ?
Nils Maier
Most extensions are already a combination of javascript + xul + css (and sometimes some xbl).
Throw in some dtd/properties files if you want some l10n and you’re done.
There is only a handful of extensions that actually uses C++.
So it is already pretty “webby” on the implementation side.
I say the way to go is simply to provide more FUEL-like APIs. Including jquery would be a great thing to do, however it has to be determined how much it might interfere with existing (extension) code.
The shared “namespace” is still a major obstacle.
Wladimir posted an article about some ways to overcome it recently, and it shows that it’s actually still not exactly easy:
http://adblockplus.org/blog/avoiding-naming-conflicts-in-overlays
As for the packaging part: In my opinion it isn’t that hard.
Installation manifests and Chrome manifests are fairly well documented on AMO and the actual packaging is as easy as zipping the whole into an archive (or two if you want chrome.jar)
There are some issues, but most likely only “advanced” extensions will encounter those. Like window icons must be in chrome/icons and may not be jar’ed.
A major area which isn’t addressed by your proposal at all is l10n.
In conclusion: Seems like a nice idea, however in my opinion the existing extensions “system” should be enhanced before thinking about an “extensions-light” variant (FUEL-like APIs, more documentation especially on how to achieve common tasks).
Dr. Pain
I’m not sure why you’re targeting any sort of “code” as the ideal extension development environment. Most extensions are trying to make the browser/web sites/a particular web site look or behave differently. Some kind of visual editor seems like a more powerful solution — edit the website (your browser) to your liking and then automatically create the extension that gives you that functionality. Platypus goes a little ways down this road but is limited by using Greasemonkey for implementation.
Jonathan Bradley
I would personally like to see a better framework that could integrate with eclipse, dreamweaver, textmate or maybe a visual editor.
Marc Diethelm
Mozilla the platform… There have been lots of discussions about this in recent years and the Mozilla team pretty much decided to focus on the browser. Which was probably a good move too. But it also explains why XUL has never been spec’ed, versioned and made complete. IMO that’s were the focus, in terms of extension development (application development really), on Gecko should be: Create a version of XUL that lends itself to the building of any app (not only a browser), that provides a consistent layout on different OSs (without CSS hacking). Other things I woud consider very beneficial: an extended FUEL library and jQuery for Gecko (yes!).
I’ll say it again: XUL 1.0 and jQuery for Gecko!!
That’s just from the top of my hat, I’m at work.. ;)
Chris
A rebellious thought. What if the entire chrome was actually a website, e.g. chrome.mozilla.org? The browser would be just a rendering engine, and the first thing it would do when loaded is display http://chrome.mozilla.org which contains the address bar, menus, etc. The actual websites would be something like iFrames inside this chrome.
Firefox extension development would then be similar to programming Facebook applications, i.e. they would be hosted on the Mozilla website. You can imagine perhaps having your own chrome at http://chrome.mozilla.org/users/{userid} which could be modified by the user via a web-based front end. Or even creating your own chrome at your own domain! What’s more, you could even get a webkit or IE-based browser to display the Firefox chrome just by pointing it to your chrome URL. Any computer you connected to would then have access to your favourites, options etc just by using your chrome – as per Weave, but simpler.
Euge
Maybe it would be great to have an extension IDE or a visual-extension-creator-editor-etc”tor”…
I just finished a (2 hours!) GREAT session with Myk Melez and the guys/girls from the design challenge 2009!
It was really a Bootcamp! (like the tittle of the session). I hope this will be available in a more “easy” way for the not-so-developer people (some code is always necessarily).
Greeting from Argentina!
pd:sorry about my english :-)
Mike
The biggest problem in extensions now is their disability to install without relaunching Firefox. I oftenn notice that it’s takes too long time for me and that why I install the extencion only when I really really want it.
Extensions could be like cookies. Any site should have possibility to install extension to your browser without relaunching browser. And you could allow or don’t them to do it.
It could completely change the way how sites are built. For example, when you open gmail and allow their extension they could make special panel with a number of unread messages in your browser. They could add some buttons to firefox interface. Maybe it will be look much more like you opening desctop software. Firefox could transform interface from site to site adpting to what they need.
Kelvin65
Mark,It’s not Google’s fault that there’s not a proper app. ,
Zayıflama Lida Fx15 Ve Biber Hapı Zlfvbh
If im understanding this correctly, then you’d be able to update extensions without having to restart the browser. Essentially extensions would turn into more integrated stylish, or greasemonkey scripts. amirite?
porno
In all the extensions that I have there is a “stdlib” directory next to my other “modules” directory for my resource.
Sex
In all the extensions that I have there is a “stdlib” directory next to my other “modules” directory for my resource.
göt sikiş
Positive reinforcement is far more effective than negative reinforcement. It’s as true for people as it is for animals. But, why?
diziizle
This includes all the stuff that should be easy but isn’t, it’s an attempt to abstract a lot of the nastier more difficult tasks that I have to do over and over again.
basur
If im understanding this correctly, then you’d be able to update extensions without having to restart the browser. Essentially extensions would turn into more integrated stylish, or greasemonkey scripts. amirite?
wholesale beads
that is a question about buying wholesale beads from china
NOELLE
Hello, Good morning I have been looking for content like this for a research project i am working. Greetings from Iowa
my blog
I’m looking for these material, thank you, this is very helpful to me.thx for bloger.
Anonymous
Many thanks for a great and insightful article I truly value all the effort in which went into the producing.
Anonymous
I know I’m a bit late in contributing my ideas but this particular write-up made me feel. It was an absorbing weblog submit. I have become a frequent reader of the website because I stumbled on your website a while back again. I can not say that I agree with every thing you stated however it was emphatically enlightening! I will likely be back again again soon.
Brandon Schlaefer
Its an absolute certainty that a Significant Lottery Player, properly using a quality Lottery Software supplement, can improve their chances of winning the lottery.
viagra
Unquestionably imagine that which you stated. Your favorite reason seemed to be on the internet the easiest factor to bear in mind of. I say to you, I certainly get irked at the same time as other folks think about issues that they just do not realize about. You managed to hit the nail upon the highest and defined out the whole thing without having side-effects , other people can take a signal. Will probably be back to get more. Thank you