What XPCOM interfaces should I use to detect opening, closing and switching of tabs and also get their associated URL from a firefox extension? I have seen instances of code that manage tabs in JS, but how about from C++ ?
Asked
Active
Viewed 2,490 times
3
-
Why? You should definitely do this from JS. – Nickolay Nov 18 '09 at 17:08
1 Answers
5
You can write small JS component that will reroute tab events to your C++ component using nsIObserverService.
In C++ code you can use this snippet to register your component as observer to user defined events that is used for rerouting tab events.
NS_IMETHODIMP MyCppComponent::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *aData)
{
if( !strcmp( aTopic, "xpcom-startup" ) )
{
nsCOMPtr<nsIObserverService> observerService =
do_GetService( "@mozilla.org/observer-service;1" );
observerService->AddObserver( this, "my-tab-open", false );
observerService->AddObserver( this, "my-tab-close", false );
observerService->AddObserver( this, "my-tab-select", false );
}
else if( !strcmp( aTopic, "my-tab-open" ) )
{
/* . . . */
}
else if( !strcmp( aTopic, "my-tab-close" ) )
{
/* . . . */
}
else if( !strcmp( aTopic, "my-tab-select" ) )
{
/* . . . */
}
/* . . . */
}
And in helper JS component you should to subscribe to tab events and in event handlers you can extract desired data and raise user defined events to execute C++ code.
function tabOpened(event) {
var obsSvc = CC["@mozilla.org/observer-service;1"].
getService(CI.nsIObserverService);
obsSvc.notifyObservers(event.target.linkedBrowser.contentWindow,
"my-tab-open", "some data");
}
function tabClosed(event) {
var obsSvc = CC["@mozilla.org/observer-service;1"].
getService(CI.nsIObserverService);
obsSvc.notifyObservers(event.target.linkedBrowser.contentWindow,
"my-tab-close", "some data");
}
function tabSelected(event) {
var obsSvc = CC["@mozilla.org/observer-service;1"].
getService(CI.nsIObserverService);
obsSvc.notifyObservers(event.target.linkedBrowser.contentWindow,
"my-tab-select", "some data");
}
function contentWndLoad(event) {
var obsSvc = CC["@mozilla.org/observer-service;1"].
getService(CI.nsIObserverService);
var browser = getMostRecentBrowserWindow().getBrowser();
browser.tabContainer.addEventListener("TabOpen", tabOpened, false);
browser.tabContainer.addEventListener("TabClose", tabClosed, false);
browser.tabContainer.addEventListener("TabSelect", tabSelected, false);
}
MyJsComponent.prototype = {
/* . . . */
observe: function(aSubject, aTopic, aData) {
switch(aTopic) {
case "xpcom-startup":
var obsSvc = CC["@mozilla.org/observer-service;1"].
getService(CI.nsIObserverService);
obsSvc.addObserver(this, "toplevel-window-ready", false);
break;
case "toplevel-window-ready":
aSubject.addEventListener("load", contentWndLoad, false);
break;
}
}
/* . . . */
}
Also there are some additional code that you should add to handle specific cases. For instance when user close browser window you won't receive TabClose events for opened tabs in that window... And don’t forget to unregister your observers when you longer need them.

Mladen Janković
- 7,867
- 3
- 22
- 26
-
Great, This was exactly what I needed, the example code will save me a lot of time!!! Thanks a million!!! – rep_movsd Nov 20 '09 at 11:20