Progress listeners: Difference between revisions

From MozillaZine Knowledge Base
Jump to navigationJump to search
Line 61: Line 61:
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).
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).


== Example: OnChangeLocation ==
== Example: Getting notified when the value in Location Bar changes ==
<ol>In order to only receive a change location event whenever the address bar changes (the "easier method" linked above fires onload events only - not fired when the user uses the back button and loads a page from cache) use the follow code...
A commonly asked question is how to get notified whenever the URL in the [[Location Bar]] (also known as address 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.
<pre>
<pre>
var oldURL = null;
var myExt_urlBarListener = {
var urlBarListener =
{
   QueryInterface: function(aIID)
   QueryInterface: function(aIID)
   {
   {
Line 76: Line 74:
   },
   },


   onStateChange: function(aProgress, aRequest, aFlag, aStatus)
   onLocationChange: function(aProgress, aRequest, aURI)
   {
   {
  if(aFlag & STATE_START)
    myExtension.processNewURL(aURI);
  {
    // 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 )
   onStateChange: function() {},
   {
  onProgressChange: function() {},
     processNewURL(aURI);
  onStatusChange: function() {},
     return 0;
  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);
   },
   },


   // For definitions of the remaining functions see XulPlanet.com
   processNewURL: function(aURI) {
  onProgressChange: function() {return 0;},
    if (aURI.spec == this.oldURL)
  onStatusChange: function() {return 0;},
      return;
  onSecurityChange: function() {return 0;},
   
  onLinkIconAvailable: function() {return 0;}
    // now we know the url is new...
}
    alert(aURI.spec);
 
    this.oldURL = aURI.spec;
document.addEventListener( "load", initializeClient, true );
  }
 
};
function initializeClient()
{
  // Listen for webpage loads
  gBrowser.addProgressListener( urlBarListener,
      Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
}


function processNewURL(aURI)
document.addEventListener("load", function() {myExtension.init()}, false);
{
document.addEventListener("unload", function() {myExtension.uninit()}, false);
  if (aURI.spec == oldURL)
    return;
 
  // now we know the url is new...
  alert(aURI.spec);
  oldURL = aURI.spec;
  return;
}    
</pre>
</pre>
</ol>


[[Category:Example code]] [[Category:XPCOM example code]] [[Category:JavaScript example code]]
[[Category:Example code]] [[Category:XPCOM example code]] [[Category:JavaScript example code]]

Revision as of 01:21, 15 January 2006

This page is part of the extension development documentation project.

Ask your questions in MozillaZine Forums. Also try browsing example code.

Note: development documentation is in process of being moved to Mozilla Development Center (MDC).

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.

Example

  1. 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(aProgress, aRequest, aFlag, aStatus)
      {
       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
       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;}
    }
  2. Attach the progress listener to a <browser> or a <tabbrowser> element, e.g. for Firefox put the following code in a load listener 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 recieved. All six progress handler functions must be defined, even if filters are used.

Remember to change myListener to an 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).

Example: Getting notified when the value in Location Bar changes

A commonly asked question is how to get notified whenever the URL in the Location Bar (also known as address 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;
  }
};

document.addEventListener("load", function() {myExtension.init()}, false);
document.addEventListener("unload", function() {myExtension.uninit()}, false);