A Wrench in the Works – Multiple Tabs in Firefox
The code from my previous post worked great with a single tab open in Firefox. However, using multiple tabs exposed a problem – all tabs in a single Firefox window share the same status bar. Another issue is that the event “DOMContentLoaded” gets fired any time a page finishes loading, regardless of what tab you’re on. This means that the information in the status bar may or may not actually match the tab that you’re on.
I also found some better techniques for placing my code in a namespace/module that are described here and here. It’s also worth noting that Mozilla’s Developer Center has documentation for their Javascript APIs and objects. Unfortunately, the documentation usually isn’t very good and I wind up spending an awful lot of time looking for simple pieces of information.
After a bit of work, I came up with the code below to do what I wanted. This code only works for Firefox 3.5 because that’s when event data was added for the TabOpen, TabClose, and TabSelect events. In the code below, event.data is a BrowserTab object.
// Create a global variable for the addon
var g17of26 = {};
g17of26.eHowEarningsTracker = function ()
{
// Private functions
var updateStatusBar = function(msg)
{
var statusBar = window.document.getElementById("ehow_earnings_tracker_statusbar");
if(statusBar)
{
statusBar.setAttribute("label", msg);
}
}
return { // This brace must stay on the same line as the return - it's a Javascript quirk
// This function is called when the browser is first launched
onBrowserLoad : function()
{
Application.activeWindow.events.addListener("TabOpen", g17of26.eHowEarningsTracker.onTabOpen);
Application.activeWindow.events.addListener("TabClose", g17of26.eHowEarningsTracker.onTabClose);
Application.activeWindow.events.addListener("TabSelect", g17of26.eHowEarningsTracker.onTabSelect);
Application.activeWindow.activeTab.events.addListener("load", g17of26.eHowEarningsTracker.onTabLoad);
},
// This function is called when the browser quits
onBrowserUnload : function()
{
window.removeEventListener("load", g17of26.eHowEarningsTracker.browserLoad, false);
window.removeEventListener("unload", g17of26.eHowEarningsTracker.browserUnload, false);
Application.activeWindow.events.removeListener("TabOpen", g17of26.eHowEarningsTracker.onTabOpen);
Application.activeWindow.events.removeListener("TabClose", g17of26.eHowEarningsTracker.onTabClose);
Application.activeWindow.events.removeListener("TabSelect", g17of26.eHowEarningsTracker.onTabSelect);
},
// This function is called when a tab is opened
onTabOpen : function(event)
{
event.data.events.addListener("load", g17of26.eHowEarningsTracker.onTabLoad);
},
// This function is called when a tab is closed
onTabClose : function(event)
{
event.data.events.removeListener("load", g17of26.eHowEarningsTracker.onTabLoad);
},
// This function is called when a tab is selected
onTabSelect : function(event)
{
updateStatusBar(Application.activeWindow.activeTab.uri.spec);
},
// This function is called when a page finishes loading in a tab
onTabLoad : function(event)
{
if(event.data.uri.spec == Application.activeWindow.activeTab.uri.spec)
{
updateStatusBar(event.data.uri.spec);
}
}
};
}(); // the parens here cause the anonymous function to execute and return
// Hook up events
window.addEventListener("load", g17of26.eHowEarningsTracker.onBrowserLoad, false);
window.addEventListener("unload", g17of26.eHowEarningsTracker.onBrowserUnload, false);