The first thing you need to do is create a directory for your extension. I put mine in ~/extensions/backlog. In that directory we're going to put 4 files:
chrome.manifest tells Firefox where the files are for the extension. This is right out of the Mozilla documentation.
content backlog content/
overlay chrome://browser/content/browser.xul chrome://backlog/content/overlay.xul
install.rdf tells Firefox meta information about the extension:
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>backlog@viscog.cs.drexel.edu</em:id>
<em:name>Back Log</em:name>
<em:version>1.0</em:version>
<em:description>Add history log entries when hitting back button</em:description>
<em:creator>Walt Mankowski</em:creator>
<em:homepageURL>http://kb.mozillazine.org/Getting_started_with_extension_develop ment</em:homepageURL>
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>3.0</em:minVersion>
<em:maxVersion>3.0.*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>
Most of that is boilerplate. The most important field is em:id, because that's how you'll identify it to Firefox later on. Note that it has to be in the form of an email address, though it doesn't actually have to be a valid email address. In this extension it's important that em:minVersion is set to 3.0, since I'm using a Firefox 3.0 feature to do the logging.
content/overlay.xul tells Firefox what part of the browser we want to extend. In the tutorials they do things like add "Hello, world" somewhere in the browser window. Here I want to leave the window itself alone and just add some javascript.
<?xml version="1.0"?>
<overlay id="backlog-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="overlay.js"/>
</overlay>
content/overlay.js is the javascript code that does the logging when the forward and back buttons are pressed.
window.addEventListener("load", function() { Backlog.onLoad(); }, false);
var Backlog = {
onLoad: function() {
// initialization code
var appcontent = document.getElementById("appcontent"); // browser
if (appcontent)
appcontent.addEventListener("pageshow", Backlog.onPageShow, true);
},
onPageShow: function(aEvent) {
var doc = aEvent.target;// doc is document that triggered "onPageShow" event
// this service is Firefox's API for logging history events
var historyService = Components.classes["@mozilla.org/browser/nav-history-service;1"]
.getService(Components.interfaces.nsIGlobalHistory2);
if (aEvent.persisted)// page pulled from cache, so log it
historyService.addURI(doc.documentURIObject, false, true, null);
}
};
When the overlay is loaded, I add a listener for the pageshow event. This event is triggered both when a new page is displayed (e.g. when clicking on a hyperlink) and when a page is pulled out of the cache via the forward or back buttons. When the event occurs, I check the persisted flag. This is set to true when the page is in the session history, i.e. we've already seen the page once, and now we're seeing it again with Forward or Back. Firefox normally doesn't add these pages again to its history database, but that's exactly what I wrote this extension to do. To write the URI out history, I call addURI() in the nsIGlobalHistory2 service.
It's possible to package up extensions so that they install automatically, but since I only need this to run on a single box I didn't bother. Instead I just followed the instructions for testing extensions. It turns out that while extensions themselves contain lots of ugly XML and javascript code, testing them is really easy. Just go to your Firefox profile directory. (On my box it's ~/.mozilla/firefox/.default.) Then go one level deeper to the extensions directory. In that directory, create a file whose name is the id of the extension ("backlog@viscog.cs.drexel.edu" in this case). The file should contain a single line containing thee root path of the extension ("~/extensions/backlog"). Finally restart Firefox, and you should see a message saying that it's found a new extension. If you decide to disable the extension, just remove the file from the extensions directory and restart Firefox.
em:id doesn't have to be an email address (Score:1)
Re: (Score:1)
I suppose I should add that this is the first XML and Javascript I've written in nearly a decade, so there are undoubtedly things I could have done better. For instance, looking at the code again, I probably should have just gotten the service once instead of doing it for every single page. Oh well.