I am chasing down a bug in a FireFox extension. I've finally managed to see it for myself (I've only had reports before) and I can't understand how what I saw is possible.
One error message from my extension in the Error Console is "gBrowser is not defined". This by itself would be surprising enough, since the overlay is over browser.xul and navigator.xul, and I expect gBrowser
to be available from both. Even worse is the actual place where it happens: line 101 of nextplease.js. That is, inside the function isTopLevelDocument
, which is only called from onContentLoaded
, which is only called from onLoad
here:
gBrowser.addEventListener(this.loadType, function (event) {
nextplease.loadListener.onContentLoaded(event);
},
true);
So gBrowser
is defined in onLoad
, but somehow undefined in isTopLevelDocument
.
When I tried to actually use the extension, I got another error: "nextplease is not defined". The interesting thing is that it happened on lines 853 and 857. That is, inside the functions
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);
}
So nextplease
is somehow defined enough to call these functions, but isn't defined inside them.
Finally, executing typeof(nextplease)
in Execute JS returns "object". Same for gBrowser
.
How can this happen? Any ideas?
These days, most cross-browser JavaScript problems are seen: When poor-quality browser-sniffing code, feature-detection code, and vendor prefix usage block browsers from running code they could otherwise use just fine. When developers make use of new/nascent JavaScript features, modern Web APIs, etc.)
If there is no error in console and still JS code not working, may be you have not invoked the code. Check if the code is reachable. If none of the above works, there is a possibility that JS is disabled in the browser you are trying to run the code. Enabling JS should work.
The JavaScript exception "variable is not defined" occurs when there is a non-existent variable referenced somewhere.
The JavaScript in operator is used to check if a specified property exists in an object or in its inherited properties (in other words, its prototype chain). The in operator returns true if the specified property exists. Anatomy of a simple JavaScript object.
For the second case:
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);
}
I'd try this instead:
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);
}
I'm not sure what's happening (in which context the code is running and therefore why it's not seeing the gbrowser and other global variables) but an easy workaround for gbrowser being undefined would be to get a reference to the main window and access it from there:
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( ... )
This should work independently of the context where the code is running since you would not rely on global variables.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With