An example of modifying a Firefox extension

April 8, 2011

I've written vaguely a while back about modifying Firefox extensions. I just needed to do this again, so this time I am going to write down a much less vague and more detailed discussion of what I did.

The basics are that I modified the current version of All-in-One Gestures to add new 'View page in no style' and 'View page in basic style' actions that could be associated with a gesture (these are normally accessible through View → Page Style). I wanted this because I use 'view page in no style' fairly frequently to deal with websites with bad formatting, bad colour choices, and so on.

The procedure I followed goes like this:

  • find the directory for this extension, following the outline in the previous quick intro.
  • find the actual .jar file, which in this case was chrome/allinonegest.jar.
  • copy the .jar to /tmp and unpack it in a subdirectory, in this case /tmp/b.

  • look through the resulting collection of files for likely files to look at to find the code for actions. I settled on content/allinonegest/gestimp.js, which turned out to be what I want; it had a big array of the available actions with the code that they ran. However, it did not have the actual names of the various actions, just labels for them like g.pasteAndGo.

    Having found the right place, I added the basic skeleton of an implementation in the form of two table entries to call aioNoStyle() and aioBasicStyle() functions, and stub implementations of those two functions.

    (The 'aio...' names are the style of function naming that was already in use in gestimp.js. When I'm hacking stuff into foreign code like this I tend to follow its style whenever possible.)

  • grep through all of the extension's files to find out where the names of the actions were defined, using one of the existing action labels. This turned up a bunch of locale files for various languages, of which I only cared about locale/en-US/allinonegest/allinonegest.properties.

    Having found the right place, I added appropriate text names for my new actions.

    (If I was doing this for general use I would need to figure out what to do in other locales. Since the only locale I use myself is en-US, I don't care and I can take a shortcut.)

  • it turned out that I wasn't quite done yet, because this didn't make my new additions appear in All-in-One Gestures' preferences system. Searching through the extension's files once again for an existing action label turned up content/allinonegest/pref/customize.js, which had a big array (again) of all of the available actions. So I added my new actions to this array.

  • now I needed an actual implementation of turning off and on the page styles. The easiest way to do this was to steal it from the existing Firefox code; in order to find that code, I worked backwards from the menu name using my copy of the Firefox source.

    • search through the Firefox source for where the text 'No Style' occurs. This pointed to browser/locales/en-US/chrome/browser/browser.dtd, and inspection of that showed that the label for this text was pageStyleNoStyle.
    • search through the Firefox code again for where pageStyleNoStyle is used, which turned up browser/base/content/browser-menubar.inc. Inspection of this showed that this menu item had JavaScript defined that simply called setStyleDisabled(true);.

    (As a cautious check I then found setStyleDisabled()'s implementation and verified that it looked usable and, in this case, simple.)

  • having found what I needed to do, I modified gestimp.js to change my stub implementations of aioNoStyle() and aioBasicStyle() to just call setStyleDisabled() with appropriate arguments. (I correctly guessed that setStyleDisabled(false); would do the 'view page in basic style' action.)

  • repack the jar by running zip -f ../allinonegest.jar in /tmp/b.
  • install the new .jar by quitting Firefox, making a backup copy of the original .jar, copying the new .jar into the All-in-One Gestures extension directory, and restarting Firefox.

With all of this done I could call up the addon preferences for All-in-One Gestures and add actual gestures for my new actions.

(As you might guess, this actually took two iterations; on the first iteration I didn't know that I needed to modify a third file to make my new actions appear in the AiO preferences.)

After I did all of this I unpacked a pristine copy of the extension in /tmp/a and made myself a diff of the two trees for future use. For example, should All-in-One Gestures ever have another official release and I need to re-apply my modifications.

(Sadly, AiO appears to be more or less abandoned by its original author. This is a real pity and is one of the reasons that I don't feel all that enthused about Firefox 4.)


Comments on this page:

From 91.215.79.84 at 2011-04-09 06:24:13:

With FireGestures (which seems to be actively maintained) there is no need to modify the extension code — you can add custom JavaScript actions directly in the settings window. And on http://www.xuldev.org/firegestures/getscripts.php there is even a script called “Enable / Disable Page Style”.

By cks at 2011-04-11 11:44:19:

For various reasons I've never looked at alternatives to All-in-One Gestures. Part of this is that I'm really used to AiO's set of gestures and the thought of either learning new gestures or recreating all of AiO's gestures wasn't really appealing when AiO worked fine.

(Mind you, for all I know everyone uses basically the same set of gestures. But I don't know and finding out would take more work than this seems to justify.)

Written on 08 April 2011.
« Why I don't like Solaris boot archives, illustrated
The evolution of the git tree format »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Fri Apr 8 23:59:02 2011
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.