Add-ons using the techniques described in this document are considered a legacy technology in Firefox. Don't use these techniques to develop new add-ons. Use WebExtensions instead. If you maintain an add-on which uses the techniques described here, consider migrating it to use WebExtensions.
From Firefox 53 onwards, no new legacy add-ons will be accepted on addons.mozilla.org (AMO).
From Firefox 57 onwards, WebExtensions will be the only supported extension type, and Firefox will not load other types.
Even before Firefox 57, changes coming up in the Firefox platform will break many legacy extensions. These changes include multiprocess Firefox (e10s), sandboxing, and multiple content processes. Legacy extensions that are affected by these changes should migrate to WebExtensions if they can. See the "Compatibility Milestones" document for more.
A wiki page containing resources, migration paths, office hours, and more, is available to help developers transition to the new technologies.
This article is for XUL/JavaScript developers who want to have custom code executed each time a new page is loaded in browser/mail. If you need finer control over custom code execution—for example, as documents are loading or when tabs are switched—see Progress Listeners.
Progress listeners allow extensions to be notified of events associated with documents loading in the browser and with tab switching events. Progress listeners implement the nsIWebProgressListener interface.
Creating an overlay
First, you need to create an overlay to one (or more, depending on which applications you target) of the following XUL documents:
Application | URI to overlay |
---|---|
Firefox | chrome://browser/content/browser.xul |
Thunderbird | chrome://messenger/content/messenger.xul |
Navigator from SeaMonkey | chrome://navigator/content/navigator.xul |
Attaching a script
Attach a script to your overlay (see "Attaching a Script to an Overlay") that adds a load
event listener to appcontent
element (browsers) or messagepane
(mail):
window.addEventListener("load", function load(event){ window.removeEventListener("load", load, false); //remove listener, no longer needed myExtension.init(); },false); var myExtension = { init: function() { var appcontent = document.getElementById("appcontent"); // browser if(appcontent){ appcontent.addEventListener("DOMContentLoaded", myExtension.onPageLoad, true); } var messagepane = document.getElementById("messagepane"); // mail if(messagepane){ messagepane.addEventListener("load", function(event) { myExtension.onPageLoad(event); }, true); } }, onPageLoad: function(aEvent) { var doc = aEvent.originalTarget; // doc is document that triggered "onload" event // do something with the loaded page. // doc.location is a Location object (see below for a link). // You can use it to make your code executed on certain pages only. if(doc.location.href.search("forum") > -1) alert("a forum page is loaded"); // add event listener for page unload aEvent.originalTarget.defaultView.addEventListener("unload", function(event){ myExtension.onPageUnload(event); }, true); }, onPageUnload: function(aEvent) { // do something } };
Current Firefox trunk nightlies will fire the onPageLoad function for not only documents, but xul:images
(favicons in tabbrowser). If you only want to handle documents, ensure aEvent.originalTarget.nodeName == "#document"
.
If you are running code on a page load it is likely you would want to run some cleanup code on page unload. To attach to the unload event in above example you can use the "pagehide" event like this:
appcontent.addEventListener("pagehide", myExtension.onPageUnload, false);
for appcontent
and similarly for messagepane
messagepane.addEventListener("pagehide", myExtension.onPageUnload, false);
and add your code to onPageUnload
method.
Basic onPageLoad for a browser window
var myExtension = { init: function() { // The event can be DOMContentLoaded, pageshow, pagehide, load or unload. if(gBrowser) gBrowser.addEventListener("DOMContentLoaded", this.onPageLoad, false); }, onPageLoad: function(aEvent) { var doc = aEvent.originalTarget; // doc is document that triggered the event var win = doc.defaultView; // win is the window for the doc // test desired conditions and do something // if (doc.nodeName != "#document") return; // only documents // if (win != win.top) return; //only top window. // if (win.frameElement) return; // skip iframes/frames alert("page is loaded \n" +doc.location.href); } } window.addEventListener("load", function load(event){ window.removeEventListener("load", load, false); //remove listener, no longer needed myExtension.init(); },false);
References
- If you need to have a more complicated listener (not just onload), use Progress Listeners.
See also
- DOMContentLoaded event in Listening to events: Simple DOM events