Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

waltman (335)

waltman
  (email not shown publicly)

Journal of waltman (335)

Wednesday July 30, 2008
10:45 PM

Logging back and forward buttons in Firefox

[ #37060 ]
As promised, here's my extension. First, a disclaimer. Though it's unlikely with something this simple, buggy extensions can mess up your Firefox profile, including your bookmarks, cookies, plugins, preferences, and so on. If you're paranoid, see the Firefox documentation on how to create a development profile.

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
  • install.rdf
  • content/overlay.xul
  • content/overlay.js

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.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • em:id doesn't have to be an email address, it just has to be unique amongst all extensions. (GUIDs used to be recommended, but not any more, I don't think.)
    • Thanks. I do remember reading that, now that you mention it. Email addresses do seem an odd way to tag things.

      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.