Firefox onLocationChange не всегда называется

Я создаю расширение firefox, которое создает несколько скрытых элементов браузера.

Я хотел бы addProgressListener() обрабатывать onLocationChange для загружаемой страницы. Однако мой обработчик не всегда вызывается.

В частности, вот что я делаю:

  • Создайте элемент браузера без установки его свойства src
  • Прикрепите его к другому элементу
  • Добавить прослушиватель хода прослушивания onLocationChange в элемент браузера
  • Вызовите loadURIWithFlags() с требуемым URL-адресом и отправкой данных

Я ожидаю, что обработчик будет вызываться каждый раз после 4, но иногда он не работает (кажется, он застрял на тех же страницах).

Интересно, что если я обертываю 3 и 4 внутри setTimeout(..., 5000);, он работает каждый раз.

Я также попытался перетасовать некоторые из шагов, но это не имело никакого эффекта.

Чем больше картинка: я бы хотел быть уверенно уведомлен, когда браузер contentDocument - это только что загруженная страница (после перенаправления). Есть ли лучший способ сделать это?

Обновление. С тех пор я открыл ошибку в mogilla bug tracker с минимальным приложением xulrunner, отображающим это поведение, в случае, если кто-то хочет более внимательно посмотреть: https://bugzilla.mozilla.org/show_bug.cgi?id=941414

Ответ 1

По моему опыту разработки с Firefox я обнаружил, что в некоторых случаях код инициализации для различных элементов действует так, как если бы он был асинхронным. Другими словами, когда вы закончите выполнение

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

ваш browser, возможно, еще не готов. Когда вы добавляете задержку, у всех есть время для инициализации, поэтому они работают нормально. Кроме того, когда вы делаете такие вещи, как динамическое создание элементов browser, вы, вероятно, делаете то, что очень немногие пробовали раньше. Другими словами, это звучит как ошибка в Firefox, и, вероятно, тот, который не получит большого внимания.

Вы говорите, что используете onLocationChange, чтобы вы могли узнать, когда добавить слушателя load. Я собираюсь предположить, что вы добавляете слушателя load к contentDocument, так как вы упомянули об этом. Вместо этого вы можете добавить слушателя load к самому browser, как и к iframe. Если я заменил

newBrowser.addProgressListener(listener);

с

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

то я получаю уведомления для каждого browser.