Firefox add-ons, or extensions, are small programs that run inside the browser in order to customize some behaviors. In theory, it is possible to develop and maintain a multilingual, multiversion and multiOS Firefox add-on. In practice, there are many obstacles to overcome in order to create and to maintain a working Firefox add-on in one language for one Firefox version and for one OS.

A Need Arises

In February 2005, I decided to join Wikipedia: free knowledge for everybody. Yes, everybody, even if you read Farsi like the people in that Middle East country. At first, I was contributing 5, 10 times a day. Then I really got hooked, I peaked to 50, 60 contributions a day. However, there was a problem, a itch to scratch as some would say.

To read and to modify the articles, I used Firefox for many reasons: it has tabs, the rendering engine is good, it has tabs, you can customize it endlessly, it has tabs, you can prevent image loading, it has tabs,... You see the picture. Wikipedia contributors provided a bunch of scripts to ease edition, but none was offering what I wanted; open a page on 20th century politics for instance, read for a while, see "JFK" in plain text (not hyperlinked), select it, and tell Firefox to open the page entitled JFK on a click. Why in the world would I need this feature? I am glad you asked. What is the meaning of JFK ? Is there an article entitled JFK? If it is an acronym, does it have many significations? (Insert your question here). If any question receives a yes, then "JFK" should be wikified (in other words, it should be hyperlinked to the article entitled "JFK").

Since I was not the first to edit and read Wikipedia pages, there was probably someone who built an add-on having such a feature. After perusing different Web sites (Google, thank you!), the reality sank in: nobody provided such an extension.

Being a software developer for five years, I decided to be the knight who saved the day, my day. That was in October 2005.

First Runs

After browsing different sites, most notably the Mozilla Developer Center, I downloaded and reverse-engineered some add-ons. What I found was simple on the surface, but developer unfriendly underneath.

Each add-on is packaged within an XPI file. Sometimes, I found a .jar file inside the .xpi file. After a while, I figured that XPI and JAR file formats are ZIP format in disguise. Still today, I find this file structure unfriendly since I must uncompress the .jar file to view its content and there is no significant gain from compressing a .jar file. However, I will not launch a crusade for that.

There are two files of utmost importance: "chrome.manifest" (the chrome, in Firefox parlance, is a portion of the graphical interface) and "install.rdf" (RDF is a language used to ease add-on update). Whenever I play with those files, I do it with care. Even today, 300 hours later, once the add-on loads properly, I just do not touch them anymore. If any has an error, Firefox either aborts the updating process with no or useless message, or performs the update while missing to do some basic checks. This is developer unfriendly.

In many add-ons, .js files appear beside .xul files. In .js files, I found straight JavaScript mixed with object-oriented JavaScript. Nothing worrisome for me, since I coded in C (a functional programming language from which JavaScript borrowed many ideas), then in C++ (an object-oriented programming language). In .xul files, there was XML sentences, close to the usual HTML sentences. Again, not too worrisome for me, since I played a lot with .html files. There were .css files used to manage the display of the elements in the dialogs . I had already seen that before, and knew what amazing things CSS could do. Finally, there was something called DTD (more on this later).

When I started coding in XUL (a language used to build graphical interface), I hit a wall. Even if XULPlanet was full of examples and descriptions, there was too many things to master. You want to display a button? No problem: <button class="CSS class" label="&DTD variable;" oncommand="JavaScriptFunction();"/a> As you can see, one XUL sentence covers many languages: XML, CSS, DTD, and JavaScript. Thus, you must resign yourself to be lost for a while when playing with XUL files. Once you have a working recipe for any XUL element, do not change it unless you are ready to walk again the long road of learning.

Being confident in my knowledge and know-how, I coded a short piece, and it worked the first time: it was the simple line alert('Hello World!'); inserted within a bunch of supporting code. Now, I could get into serious business.

After learning and coding for 50 hours, I had what I wanted: a way to click on plain text and tell Firefox to open a page. This is a pretty long scratching! But it was not enough. I wanted to open any Wikipedia page from any writeable and any readable HTML element. Another 20 hours was enough to get the job done, fixing some bugs in the process and adding some dialogs.

It was time to publish. I uploaded the 0.1 version to the Mozilla repository site. Five days later, I sent the 0.2 version, followed by the 0.3 version six days after. A week passed by, a reviewer rejected versions 0.1 and 0.2 since version 0.3 was the last in. That version was accepted.

I felt I was someone.

As I learned in a previous job, documentation is good for business. I could insert text at the Mozilla site, but it did not offer a way to publish HTML files with pictures and hyperlinks. I wrote a user's guide and hosted it somewhere else. With time, I expanded the guide to the point it has more than 30 pages today. I believe this is one strength of my add-on.

Even if it was good, the add-on needed some publicity. Thus, I wrote a short text and posted it on the French Wikipedia. Some users responded with enthusiasm, many yawned. I did not understand their lack of reaction. Many contributors complained they wanted to do more in less time. Weekedit would help them, in my opinion. Today, I respect their decision.

In March 2007, the Mozilla Foundation moved all add-ons from mozilla.org to mozilla.com. In the process, Weekedit was pushed in the sandbox, a place where it is available to users willing to try new, and sometimes shaky, things. The Foundation forgot to write me it was sandboxing my add-on, preventing regular users to install it. By luck, someone asked me if I had removed the add-on. After so many hours of work, this was absolutely out of question! I took steps to push my baby out of the dark side and in the public light. It became public two days after.

Even if it has weaknesses, the Mozilla repository is the best place to publish my add-ons. The site is multilingual, it can display some pictures, a development history is available, there is a forum, and users may leave reviews. I must say a word about the reviewers. I believe they test with care to ensure that any add-on on the site is correctly working. And they are respectful. For these two reasons, I commend them.

I18N

In April 2006, while translating articles from the English Wikipedia to the French Wikipedia, I wondered if I could build a bilingual XUL interface. The answer was and is still yes, but I needed to construct DTD files (a Document Type Definition in XML parlance). Again, I hit the road, I mean surf the Web, to learn the grammar of this new language. After many miles, I mean many pages, I was ready to build the interface in English and in French, i.e. internationalization and localization (I18N in short).

This is not straightforward as you might predict. The XUL engine (or is it the DTD engine?) cannot process plain text files containing characters with diacritics (e.g., é, à, û). When the browser loads the add-on, it displays an error message and the graphical interface does not load at all (rather harsh, in my opinion). The text must be converted to UTF-8 (a computer format to encode Unicode characters). So I got my hands on a small and free program to do the job. After that, I thought my problems with .dtd files were over. But no, I could not insert some characters from the ASCII 0-127 range, even disguised as HTML entities (like " for "). The only solution left was to create JavaScript functions to overcome that limitation.

In the course of my add-on construction, I needed to import sentences from two different DTD files within a XUL file. I read a lot and searched a lot. I finally found an add-on with the right XUL sentence. Hallelujah! However, I believe this should have been easier, but the W3C documentation is usually cryptic.

When all this mess was over, I believed my woes with the language barrier were over, but I was overly optimistic. I needed to display some messages, in English or in French, while the user was interacting with the add-on. They could not be part of any DTD files since JavaScript could not open a DTD file stream. Instead, I needed to create .properties files. The syntax of such files is simple. With all previous knowledge, it was pretty easy to insert the right code within ten minutes. Even if this worked fine, I still believe that JavaScript should be able to directly decode .dtd file content. Maybe it is the case, but I do not have any clue.

While speaking of translation, I translated to French the user's guide. That was simple: I could tell the browser that the HTML file contained French text. No need to insert UTF-8 characters. Thank god!