Объекты в JavaScript определены и undefined в одно и то же время (в расширении FireFox)
Я читаю bug в расширении FireFox. Мне, наконец, удалось увидеть это для себя (у меня были только отчеты раньше), и я не могу понять, как это возможно.
Одно сообщение об ошибке из моего расширения в консоли ошибок "gBrowser не определено". Это само по себе было бы достаточно неожиданным, так как наложение над браузером .xul и navigator.xul, и я ожидаю, что gBrowser
будет доступен из обоих. Еще хуже то место, где это происходит: строка 101 nextplease.js. То есть внутри функции isTopLevelDocument
, которая вызывается только из onContentLoaded
, которая вызывается только от onLoad
здесь:
gBrowser.addEventListener(this.loadType, function (event) {
nextplease.loadListener.onContentLoaded(event);
},
true);
Итак, gBrowser
определяется в onLoad
, но как-то undefined в isTopLevelDocument
.
Когда я попытался использовать расширение, я получил еще одну ошибку: "nextplease не определен". Интересно, что это произошло на линиях 853 и 857. То есть внутри функций
nextplease.getNextLink = function () {
nextplease.getLink(window.content, nextplease.NextPhrasesMap, nextplease.NextImagesMap, nextplease.isNextRegExp, nextplease.NEXT_SEARCH_TYPE);
}
nextplease.getPrevLink = function () {
nextplease.getLink(window.content, nextplease.PrevPhrasesMap, nextplease.PrevImagesMap, nextplease.isPrevRegExp, nextplease.PREV_SEARCH_TYPE);
}
Так что nextplease
как-то определено достаточно, чтобы называть эти функции, но не определено внутри них.
Наконец, выполнение typeof(nextplease)
в Execute JS возвращает "объект". То же самое для gBrowser
.
Как это может произойти? Любые идеи?
Ответы
Ответ 1
Для второго случая:
nextplease.getNextLink = function () {
nextplease.getLink(window.content, nextplease.NextPhrasesMap, nextplease.NextImagesMap, nextplease.isNextRegExp, nextplease.NEXT_SEARCH_TYPE);
}
nextplease.getPrevLink = function () {
nextplease.getLink(window.content, nextplease.PrevPhrasesMap, nextplease.PrevImagesMap, nextplease.isPrevRegExp, nextplease.PREV_SEARCH_TYPE);
}
Вместо этого я попробую:
nextplease.getNextLink = function () {
this.getLink(window.content, this.NextPhrasesMap, this.NextImagesMap, this.isNextRegExp, this.NEXT_SEARCH_TYPE);
}
nextplease.getPrevLink = function () {
this.getLink(window.content, this.PrevPhrasesMap, this.PrevImagesMap, this.isPrevRegExp, this.PREV_SEARCH_TYPE);
}
Ответ 2
Я не уверен, что происходит (в каком контексте работает код, и поэтому почему он не видит gbrowser и другие глобальные переменные), но легким обходным решением для gbrowser, являющегося undefined, было бы получение ссылки на главную окно и получить доступ к нему оттуда:
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindow);
mainWindow.gbrowser.addEventListener( ... )
Это должно работать независимо от контекста, в котором выполняется код, поскольку вы не будете полагаться на глобальные переменные.