Firefox onLocationChange not always called

firefox, firefox-addon, javascript, settimeout, xul

Solution

In my experience developing with Firefox, I've found in some cases the initialization code for various elements acts as if it were asynchronous. In other words, when you're done executing

var newBrowser = window.document.createElement('browser');
newBrowser.setAttribute('flex', '1');
newBrowser.setAttribute('type', 'content');
cacheFrame.insertBefore(newBrowser, null);

, your `browser` may not actually be ready yet. When you add the delay, things have time to initialize, so they work fine. Additionally, when you do things like dynamically creating `browser` elements, you're likely doing something that very few have tried before. In other words, this sounds like a bug in Firefox, and probably one that will not get much attention.

You say you're using `onLocationChange` so that you can know when to add a `load` listener. I'm going to guess that you're adding the `load` listener to the `contentDocument` since you mentioned it. What you can do instead is add the `load` listener to the `browser` itself, much like you would with an `iframe`. If I replace

newBrowser.addProgressListener(listener);

with

newBrowser.addEventListener("load", function(e) {
  console.log('got here! ' + e.target.contentDocument.location.href);
}, false);

then I receive notifications for each `browser`.

Problem

I am building a firefox extension that creates several hidden browser elements. I would like to `addProgressListener()` to handle onLocationChange for the page that I load. However, my handler does not always get called. More specifically, here's what I'm doing: - Create a browser element, without setting its `src` property - Attach it to another element - Add a progress listener listening for `onLocationChange` to the browser element - Call `loadURIWithFlags()` with the desired url and post data I expect the handler to be called every time after 4, but sometimes it does not (it seems to get stuck on the same pages though). Interestingly, if I wrap 3 and 4 inside a `setTimeout(..., 5000);` it works every time. I've also tried shuffling some of the steps around, but it did not have any effect. The bigger picture: I would like to be reliably notified when browser's `contentDocument` is that of the newly loaded page (after redirects). Is there a better way to do this? Update: I've since opened a bug on mozilla's bug tracker with a minimal xulrunner app displaying this behavior, in case anybody wants to take a closer look: https://bugzilla.mozilla.org/show_bug.cgi?id=941414

Original source