JavaScript中的对象同时定义和未定义(在FireFox扩展中)

时间:2010-02-22 23:03:12

标签: javascript firefox-addon

我正在追逐FireFox扩展程序中的bug。我终于设法自己看了(我以前只有报告),我无法理解我所看到的是可能的。

错误控制台中我的扩展程序中的一条错误消息是“未定义gBrowser”。这本身就足够令人惊讶了,因为叠加层是在browser.xul和navigator.xul之上,我希望两者都可以使用gBrowser。更糟糕的是它发生的实际位置:nextplease.js的第101行。也就是说,在函数isTopLevelDocument内,只从onContentLoaded调用,只在onLoad调用:

gBrowser.addEventListener(this.loadType, function (event) {
    nextplease.loadListener.onContentLoaded(event);
},
true);

因此gBrowser中定义了onLoad,但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以某种方式被定义为足以调用这些函数,但未在其中定义。

最后,在Execute JS中执行typeof(nextplease)会返回“object”。与gBrowser相同。

这怎么可能发生?有什么想法吗?

2 个答案:

答案 0 :(得分:2)

对于第二种情况:

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);
}

答案 1 :(得分:1)

我不确定发生了什么(代码在哪种上下文中运行,因此它没有看到gbrowser和其他全局变量)但是gbrowser未定义的简单解决方法是获取对主窗口的引用和从那里访问它:

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( ... )

这应该独立于代码运行的上下文,因为您不依赖于全局变量。