8

In my extension, I'm trying to determine whether a new tab was created as a popup by another tab and if so, which tab.

I thought I would be able to use window.opener from a content script to help figure this out. But it looks like window.opener doesn't work correctly in content scripts.

When I create a tab manually, it's window.opener is null as expected.

When a tab is created as a popup by another tab, its window.opener is undefined. I can infer from this that the tab was created as a popup, but I can't use it to figure out which tab created the new one.

Is this a known issue, and does anybody know of any workarounds?

Greg
  • 10,360
  • 6
  • 44
  • 67
  • Possible duplicate of http://stackoverflow.com/questions/3124543/is-it-possible-to-determine-a-tabs-opener-within-a-google-chrome-extension – npdoty Sep 11 '10 at 02:34
  • Yes, looks like it. But neither question has been answered.. – Greg Sep 13 '10 at 16:42
  • [We're tending to let similar questions stand, now.](http://blog.stackoverflow.com/2010/11/dr-strangedupe-or-how-i-learned-to-stop-worrying-and-love-duplication/) –  Jan 28 '11 at 13:41

1 Answers1

17

I didn't look closely into this problem, but I think I can point you in the right direction. Content script can't access a variable from a parent window because it is sandboxed. A workaround would be to run your code directly on a page, to do this you need to inject your script inside a script tag:

Your content script would look like this:

function injectJs(link) {
        var scr = document.createElement("script");
        scr.type="text/javascript";
        scr.src=link;
        (document.head || document.body || document.documentElement).appendChild(scr);
}

injectJs(chrome.extension.getURL("inject.js"));

Now you can run your code without sandbox restrictions as if it was right on the page:

inject.js:

alert(window.opener);

I assume you would like to now pass this information back to a background page, which is another challenge as you can't use Chrome API. Good news is that content script can access DOM and listen to DOM events, so you can use them to pass information to a content script which would send it to a background page. I am pretty sure you should be able to register a custom DOM event and have your content script listening to it (haven't tried this part myself).

serg
  • 109,619
  • 77
  • 317
  • 330
  • I ended up solving my problem using a method like this; injecting a lot of code into the page and using `postMessage` to communicate between frames and between the page and my content script. It's quite a pain, but it seems to work most of the time. – Greg Jan 31 '11 at 20:04
  • 3
    Any chance to see some examples of this `injected script -> content script -> background page` communication. from @Greg or @serg I'm struggling with that exact problem currently – kevzettler Jul 19 '12 at 19:29
  • 2
    @kevzettler you can inject a script which stores the `window.desiredData` as an attribute on `document.body`, and then read the attribute from your content-script (since they share the same DOM) – levi Jun 30 '14 at 23:47