Extend Firefox Without Coding C
When the Mozilla team started building its application framework back in the day, they decided to make the entire program as extensible as possible, with all layers of presentation fully separated from their behavior. This separation lets mere mortals like you and I tweak, morph, extend, and redesign the user interface without having to write any real code in order to do so.
My Firefox extension is a simple dictionary lookup widget that defines a word you type into a textbox. Yup, it’s been done before, but I thought it was a good start and gave me a good feel for the development of these things. Usually extensions can auto-install themselves from a hypertext link, but I purposely didn’t make the necessary mime-type adjustments so that you could manually install it and have it as a reference. Okay, that’s a cop out. Just download it, and then drag the XPI file to Firefox to load it.
Simpledictionary.xpi (XPI, 8KB)
An XPI file is just a ZIP archive, so after you install it change the suffix to .ZIP and expand it. Inside the chrome folder you’ll find a JAR file that you’ll need to expand as well. Now let’s check this out.
The RDF files inside the extension are the bread and butter that makes everything work. If path files are incorrect in any of the RDF files then Firefox will either crash or not even bother to load your extension. Believe me. Check every single path twice or three times, because that can save headaches later on.
For Firefox to know what’s going on, which XUL file to load, and where to find each and every part of the extension, you need to give it perfect instructions or else nothing will work. If
<em:skin> files aren’t precisely where you say they are (trailing slash necessary) then Firefox will just give up. Mozilla has a handy reference page that describes precisely what should go into an
install.rdf file, or you can follow the comments on the one I wrote.
install.rdf, these RDF files need to be perfectly formed or else the browser will throw its hands up and run away.
You define which widgets you want to replace from the default chrome in the XUL files. I found that the best way to learn how XUL operates is by opening the chrome folder inside your Firefox installation (Mac OS X users can “Show Package Contents”) and just peering through files named “browser.xul” and “searchbar.css” to see how everything fits together. If you’d like a more in-depth look at the interrelation between all these files, check out Ben Goodger’s “Getting Started w/UI Hacking” article.
The skin files design the widgets defined in the XUL files. Images, CSS, and other files are used (just like in web design!) to tell Firefox how to display each widget the way you want. These are normal CSS files, so don’t be afraid to play around.
Simpledictionary.css is the sole CSS file used to make my extension look the way it does. The good thing about extensions is that you use CSS to design the look and feel, but the bad thing is that you need to write a ton of CSS for there are few default CSS settings for widgets. You can see that my search box doesn’t natively have rounded edges or an easy way to insert the book icon so I used a PNG background-image to achieve the look I wanted. After you realize that the entire Firefox interface is designed using CSS, it’s really cool to just look at the default chrome files and see how it was all put together using
:hover states and other trickery.
Packaging Your Extension
Every tutorial I read before I embarked on my quest said that packaging your extension was easy, but time-consuming. Time-consuming it is, easy it is not. Eric Hamiter’s fantastic tutorial discusses how your directory structure needs to precisely match both 1) what Firefox is looking for, and 2) how it’s defined in your
install.rdf file. I’d suggest drawing out the exact directory tree before you start getting in too deep, just so you always have a high-level mapping you can refer back to when making your internal path and chrome links later on.
I’m using Mac OS X, and the built-in ZIP archiving capabilities leave much to be desired. For some reason the hidden files (like .DS_STORE) in folders can botch up your extension’s packaging, and because the Finder needs those files it ZIPs them up along with the real files. This causes Firefox to either 1) not register your extension, or 2) crash every single time, so I’d suggest using a build script to do it all for you. It may not seem time-consuming at the beginning, but every time you make a small change in the code you need to ZIP folders, change the suffix to JAR, delete old files, ZIP those files up, and then rename that to XPI, let alone start and restart Firefox a few times, so the time really adds up.
I had great success using Apache Ant for this script even though I had never messed with Ant before. I won’t get into it here, but you can read the Ant “Zip Task” man pages to get a handle on how to write your own
build.xml script to package everything up nicely. Or, if your extension doesn’t have a ton of functionality, you can package all your files up exactly the way I packaged Simple Dictionary, and then use my Ant script to do it for you! What a deal!
build.xml (XML, 2KB)
This is not even close to a full tutorial on what I did, but my goal was to simply whet your appetite for creating Firefox extensions. If you’d like to see live versions of any of the files used in creating my extension, just visit businesslogs.com/simpledictionary and you can navigate through the directory structure.
Here are links that I found really useful when working on this project: