iosart.com | projects | articles | photos | about

A multiplatform extension for Firefox

Update: Bug 253742 is very close to being fixed, so the workarounds in this post will no longer be needed. Thanks to the Mozilla developers for making the platform even better.

Every Firefox extension consists of several parts. It often has a UI part, typically written in XUL and some scripts typically written in Javascript. More advanced extensions have compiled XPCOM components in form of .dll or .so files.

While the XUL and the Javascript parts can often be used on all platforms (Windows, Linux etc.) without modification, the XPCOM components need to be platform specific (for obvious reasons).

I wanted to have a single extension package (XPI), which included the XPCOM components for all the platforms. When the extension is installed, it should detect the user platform and load only the appropriate components.

The first thing I noticed is that the extension manager mechanism doesn’t allow conditional installations (install different components depending on user’s platform).

Next, I tried the following reasoning: package both .dll and .so files with the extension. Firefox on Windows will load only the .dll files while ignoring the .so files, and on Linux only the .so files, while ignoring the .dll files. It was only logical to me that the Windows version of Firefox will not try to load the .so files.

It didn’t work. Windows Firefox did try to load the .so file and popped up and ugly message box saying something about wrong file format. Looking through Mozilla source code, I saw that there is a list of all the dynamic libraries extensions (.dll, .so etc.) and Mozilla will try to load all the file types on all the platforms.

After posting a question on the mozillazine.org forums, I got an answer saying that I should provide several different packages for the different platforms. I wasn’t ready to go that way. Managing several packages, when all that is different between them is a single file seemed unreasonable.

So I came up with a work-around. I had only Windows and Linux versions, but the technique can be extended further to support more platforms. Here it is:

  1. Package the Windows version of the component as MyComponent.dll
  2. Package the Linux version of the component as MyComponent.dll.linux
  3. Windows will load the .dll file while ignoring the .dll.linux file (because its extension is not a valid dynamic library extension). Nothing else should be done here.
  4. On Linux – the first time the extension is loaded, it will try to load MyComponent.dll file and fail (because the file is a Windows DLL). It will fail gracefully, without popping up any message boxes.
  5. During the startup of my extension I check whether the user platform is Linux and if MyComponent.dll.linux file exists.
  6. If so, this means that this is the first run. The script moves (renames) MyComponent.dll.linux to MyComponent.dll, removes the components registry files, compreg.dat and xpti.dat, so they are rebuilt the next time Firefox is started
    and inform the user that an additional restart is needed.
  7. When the browser is restarted, the MyComponent.dll is loaded successfully (because it is now a valid .so file) and the registry files are rebuilt to reflect its contents.
  8. The extension is now fully functional.

One little question needs to be answered – why do I rename MyComponent.dll.linux to MyComponent.dll and not to something more Linux-like as MyComponent.so.
The answer is – uninstall. If I created a new file named MyComponent.so, when my extension got uninstalled the file wouldn’t have been deleted, because it was never installed. Moving MyComponent.dll.linux to MyComponent.dll leaves all the files with exactly the same names, so when uninstall comes, they are removed.

I can provide the complete source code (in Javascript) for this technique on request.

7 Responses to “A multiplatform extension for Firefox”

  1. Jed Says:

    I would love to get my hands on the source for that.
    Thank you so much

  2. Darin Fisher Says:

    How about filing a bug in bugzilla.mozilla.org regarding this problem. I see no reason why the component loader should try to load .so files under Windows.

  3. Vladimir Says:

    Hello!

    You wrote: “I can provide the complete source code (in Javascript) for this technique on request.”

    Can yiu send me your this source code?

    Vladimir.
    mozilla@mail.ru

  4. Iosart Says:

    The code can be found in my FoxyTunes extension (foxytunesOverlay.js)

  5. Sascha Says:

    Hi,

    do you know whether the XPI script for a plugin in Firefox is the same as with an extension. I have a Mozilla XPI and I want to transform it to use it with Firefox. The plugin installs into the user folder (Documents and Settings, …) – the Plugins Folder of Firefox remains empty.

    When i load a page which needs the plugin , the plugin dll is not found. do you have any ideas?

    thanks

  6. Iosart Says:

    Sorry, I didn’t understand the problem…
    Are we talking about a specific Mozilla plugin?

  7. Sascha Says:

    Thanks for the reply. It is a plugin i wrote by myself. I wrote an install script for Mozilla 1.7 and it installs correctly in the plugins folder of Mozilla 1.7.

    I am also able to install it with the Mozilla XPI installer in Firefox – but I want to add additionally some XUL-GUI in the Firefox style.

    I tried to make a Firefox XPI package with install.rdf, … and the plugin installs into the extensions folder of the users profile. The plugin also shows up in the extensions list … but Firefox does not bind the plugin dll on startup (assumption: all plugins have to be in the plugins directory?).

    Do you have any suggestions?

    Here is the URL of the plugin: http://graphics.ethz.ch/3dwebcontent/surfelviewer/download/installation.html

    Thanks,
    Sascha