nsIWebProgressListener

One nice consequence of having a blog on our new site is that we can contribute back to the web the little details that we glean as we go about the business of coding.  When we hope a simple web search will solve our problem and it doesn't, maybe now it will for the next person.

Lately I was trying to use the nsIWebProgressListener interface in some Javascript code that runs in both a Firefox extension and a standalone app that embeds Gecko, the code that renders web pages for Firefox and other Mozilla based applications.

I could easily enough add the listener to a browser window in Firefox with addProgressListener().  But it was problematic to get the embedded equivalent, addWebBrowserListener(), to accept this in the embedded app.  My listener implemented nsISupports and would correctly advertise that it supports nsIWebProgressListener and, thanks to XPConnect, nsIWeakReference.  Despite that, addWebBrowserListener() would always return NS_ERROR_ILLEGAL_VALUE.  Unable to figure this out, I was glad to find the alternative of using a service that all progress events go through to bind my listener to: @mozilla.org/docloaderservice;1

Annoyingly, this was getting different information than the one I attached in firefox.  It would receive more events to onStateChange, but wouldn't receive onLocationChange which is very helpful for dealing with HTTP Location: header type redirects.  If you're reading this, you may appreciate the following function to enumerate exactly what flags are passed to onStateChange: