Code snippets:Progress Listeners
From MDC
[edit] 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.
Note that if you just want to execute your code each time a page loads, you can use an an easier method (onPageLoad()).
[edit] Example
- Create an object which implements
nsIWebProgressListener:const STATE_START = Components.interfaces.nsIWebProgressListener.STATE_START; const STATE_STOP = Components.interfaces.nsIWebProgressListener.STATE_STOP; var myListener = { QueryInterface: function(aIID) { if (aIID.equals(Components.interfaces.nsIWebProgressListener) || aIID.equals(Components.interfaces.nsISupportsWeakReference) || aIID.equals(Components.interfaces.nsISupports)) return this; throw Components.results.NS_NOINTERFACE; }, onStateChange: function(aWebProgress, aRequest, aFlag, aStatus) { // If you use myListener for more than one tab/window, use // aWebProgress.DOMWindow to obtain the tab/window which triggers the state change if(aFlag & STATE_START) { // This fires when the load event is initiated } if(aFlag & STATE_STOP) { // This fires when the load finishes } return 0; }, onLocationChange: function(aProgress, aRequest, aURI) { // This fires when the location bar changes; i.e load event is confirmed // or when the user switches tabs. If you use myListener for more than one tab/window, // use aProgress.DOMWindow to obtain the tab/window which triggered the change. return 0; }, // For definitions of the remaining functions see XULPlanet.com onProgressChange: function() {return 0;}, onStatusChange: function() {return 0;}, onSecurityChange: function() {return 0;}, onLinkIconAvailable: function() {return 0;} } - Attach the progress listener to a <browser> or a <tabbrowser> element, e.g. for Firefox put the following code in a
loadlistener of a main window:gBrowser.addProgressListener(myListener, Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
The second argument is a status filter which determines the type of events that will be received. All six progress handler functions must be defined, even if filters are used.
- Remember to call
removeProgressListenerin anunloadevent handler or earlier.
Remember to change myListener to a unique identifier. Also remember that if you're adding listeners inside a function, make sure to have a reference to your listener object that stays in memory (this is due to the required nsISupportsWeakReference interface). That is, the listener object shouldn't be declared solely in the temporal function.
[edit] Example: Notification when the value in Address Bar changes
A commonly asked question is how to get notified whenever the URL in the address bar (also known as location bar) changes. Using the following code, you will get notified when user navigates to another page (by clicking a link, using the back/forward button, by typing an address in the Location Bar, etc.) and also when user switches tabs.
var myExt_urlBarListener = {
QueryInterface: function(aIID)
{
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
aIID.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_NOINTERFACE;
},
onLocationChange: function(aProgress, aRequest, aURI)
{
myExtension.processNewURL(aURI);
},
onStateChange: function() {},
onProgressChange: function() {},
onStatusChange: function() {},
onSecurityChange: function() {},
onLinkIconAvailable: function() {}
};
var myExtension = {
oldURL: null,
init: function() {
// Listen for webpage loads
gBrowser.addProgressListener(myExt_urlBarListener,
Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
},
uninit: function() {
gBrowser.removeProgressListener(myExt_urlBarListener);
},
processNewURL: function(aURI) {
if (aURI.spec == this.oldURL)
return;
// now we know the url is new...
alert(aURI.spec);
this.oldURL = aURI.spec;
}
};
window.addEventListener("load", function() {myExtension.init()}, false);
window.addEventListener("unload", function() {myExtension.uninit()}, false);
Note: If you use the same listener for more than one tab/window, use aWebProgress.DOMWindow in the callback methods to obtain the tab/window which triggers the state change or event.