views:

125

answers:

1

Hi, I'm making an extension that on load of every page creates an instance of my xpcom component specifically for that page.

I do that like this:

var appcontent = document.getElementById("appcontent");   // browser
if(appcontent) {
   appcontent.addEventListener("load", onPageLoad, true);
}
var onPageLoad = function(aEvent) {
   var doc = aEvent.originalTarget; //this is the reference to the opened page
   pages.push(createInstanceOfMyXPCOM(doc));
}

My question is, within the XPCOM component, how can I use eval() within the global context of that doc. If you would just do this in a regular javascript in html you could do:

window.eval.call(window, somecode);

The problem is I don't have window variable in my xpcom component (or do I), I only have the reference to the document. I could pass the window to my XPCOM component on creation as well, but if I have several pages opened, I don't see how that would work..

A: 

From the XPCOM you should be able to get a reference to the main window using:

var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                       .getInterface(Components.interfaces.nsIWebNavigation)
                       .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
                       .rootTreeItem
                       .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                       .getInterface(Components.interfaces.nsIDOMWindow);

Then you can get the currently selected tab document with:

document = mainWindow.gBrowser.contentDocument;

You can fin more information here:

https://developer.mozilla.org/en/Code_snippets/Tabbed_browser

https://developer.mozilla.org/en/Working_with_windows_in_chrome_code

UPDATE:

Try this one, you should be able to get a reference to the most recent window:

var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                   .getService(Components.interfaces.nsIWindowMediator);
var recentWindow = wm.getMostRecentWindow("navigator:browser");

If you have multiple tabs, you use something like this (code from Mozilla Dev Site) to iterate over all of them and access each document:

var num = gBrowser.browsers.length;
for (var i = 0; i < num; i++) {
  var b = gBrowser.getBrowserAtIndex(i);
  try {
    dump(b.currentURI.spec); // dump URLs of all open tabs to console
  } catch(e) {
    Components.utils.reportError(e);
  }

}

fms
I don't think I can use the first snippet of code, because window variable is undefined in XPCOM world, though I might be wrong. Plus will having mainWindow help me execute window.eval.call(window, somecode); because I might have 3 tabs open at the same time where in each one of them I want to execute smth like window.eval.call(window, somecode).. I found evalInSandbox(code, context) yesterday, but I still didn't figure out how to pass the context to that..
Karolis
I see... just added some ideas, hope it helps. I will be working with XPCOM soon, so this is a very interesting question... make sure you write an update here once you find a solution!
fms