Firefox 6 :Problem with QueryInterface(nsIDOMWindow::GetIID() in XPCOM component, for browser content window passed from js
I am working on adding support for Firefox 6 for my add-on on Mac OS, where the following logic is working in Firefox 4,5 versions but fails in Firefox 6.
XPCOM component has subclass of IObserverClient
and which adds itself as observer for a custom event.
This custom event is posted from browser overlay.js passing the selected browser's content window.
var observerService = Components.classes["@mozilla.o开发者_StackOverflow中文版rg/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
if (observerService) {
var data = gBrowser.selectedBrowser.contentWindow.location.href;
observerService.notifyObservers(gBrowser.selectedBrowser.contentWindow, JSEventTopic, data);
}
In XPCOM components handler, trying to get the nsIDOMWindow
interface from nsISupports
void XXX::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
{
nsCOMPtr<nsIDOMWindow> pWin;
aSubject->QueryInterface(nsIDOMWindow::GetIID(), getter_AddRefs(pWin));
}
The problem is, with Firefox 6 pWin
is nil. In Firefox 4 and 5 pWin
is as expected and not nil.
The immediate problem seems to be that whatever object is being delivered as aSubject
doesn't implement the nsIDOMWindow
interface, which naturally causes the QueryInterface
to fail and yield null. You can't QI an object to an interface that it doesn't implement, and you can't QI null to anything.
I don't know off-hand what causred this change, but here are a few things to check that might help you find the real problem:
- Make sure the subject you're receiving isn't null, and that the pointer you're trying to QI is the argument received by the listener method.
- In your JavaScript code, check that the window object you're passing isn't nil, and is actually something that should implement
nsIDOMWindow
. - Check that
aTopic
contains the value you expect, and not some other event string.
I am not much familiar with add-on development. But this works for me in my application(C++).
nsCOMPtr<nsIDOMWindow> domWindow;
nsresult rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
nsCOMPtr<nsIDOMWindowUtils> windowUtils(do_GetInterface(domWindow));
精彩评论