An example of modifying a Firefox extension
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
/tmpand unpack it in a subdirectory, in this case
- 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
Having found the right place, I added the basic skeleton of an implementation in the form of two table entries to call
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.
defined that simply called
(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
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.jarin
- 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.)