nsIWebProgressListener not catching all AJAX

G’day all,

Just started working on an addon which involves a button/hotkey to stop all current and future network activity in a tab, until user initiates a change (clicking a link, typing a new addy in the bar, pressing Enter etc).

Unfortunately the following code does not appear to capture events such as those seen when typing into a search box on www.google.com or www.duckduckgo.com - a little bit stumped as to why not (it simply doesn’t fire any of these onChanges at all). :confused:

Any suggestions as to what I may be doing wrong, or another way to approach? Any help would be much appreicated :grin:

myWebProgressListener.init();
var myWebProgressListener = {
init: function() {
	var webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress);
	webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_WINDOW | Ci.nsIWebProgress.NOTIFY_LOCATION);
},
uninit: function() {
	if (!docShell) {
		return;
	}
	var webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress);
	webProgress.removeProgressListener(this);
},

onStateChange: function(webProgress, aRequest, flags, status) {
	console.log('onStateChange:', arguments);
	if (aRequest) {
		aRequest.cancel(Cr.NS_BINDING_ABORTED)
	}
},
onLocationChange: function(webProgress, aRequest, locationURI, flags) {
	console.log('onLocationChange:', arguments);
	if (aRequest) {
		aRequest.cancel(Cr.NS_BINDING_ABORTED)
	}
},
onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage) {
	console.log('onStatusChange:', arguments);
	if (aRequest) {
		aRequest.cancel(Cr.NS_BINDING_ABORTED)
	}
},
onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) {
	console.log('onProgressChange:', arguments);
	if (aRequest) {
		aRequest.cancel(Cr.NS_BINDING_ABORTED)
	}
},
onSecurityChange: function(aWebProgress, aRequest, aState) {
	console.log('onSecurityChange:', arguments);
	if (aRequest) {
		aRequest.cancel(Cr.NS_BINDING_ABORTED)
	}
},
QueryInterface: function QueryInterface(aIID) {
	if (aIID.equals(Ci.nsIWebProgressListener) || aIID.equals(Ci.nsISupportsWeakReference) || aIID.equals(Ci.nsISupports)) {
		return this;
	}

	throw Components.results.NS_ERROR_NO_INTERFACE;
}

Web progress listeners tracks the progress of requests relating to web progress. It tells you nothing at all about the masses of other network communication that is going on, either from web scripts or from addons. Or even within Firefox itself - you’d be surprised at all the stuff it does. As you found!

Use http-* observer notifications to detect all http requests and responses, although you would have to maintain your own record then of the progress of each request.

The problem is in:

webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_WINDOW | Ci.nsIWebProgress.NOTIFY_LOCATION);

When we add the listener we should specify the correct flags. To catch absolutely everything do this:

webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_ALL);

Here we ask for NOTIFY_ALL. :slight_smile:

The mask to addProgressListener (eg. NOTIFY_ALL) does not change the requests which are notified, only the individual callbacks that are made during that request. For example, NOTIFY_LOCATION only calls onLocationChange(), not onStateChange() and all the others. NOTIFY_ALL can make a crazy number of callbacks for each request, but still won’t show you requests other than the standard content loads.

Ah no way thats interesting, thanks!