0

I've been searching for examples and reference and have come up with nothing. I found a note in offscreenTab source code mentioning it cannot be instantiated from a background page (it doesn't have a tab for the offscreenTab to relate to). Elsewhere I found mention that popup also has no tie to a tab.

How do you successfully create an offscreenTab in a Chrome extension?

Rob W
  • 341,306
  • 83
  • 791
  • 678
Reinsbrain
  • 2,235
  • 2
  • 23
  • 35

1 Answers1

1

According to the documentation, offscreenTabs.create won't function in a background page. Although not explicitly mentioned, the API cannot be used in a Content script either. Through a simple test, it seems that the popup has the same limitation as a background page.

The only leftover option is a tab which runs in the context of a Chrome extension. The easiest way to do that is by using the following code in the background/popup:

chrome.tabs.create({url: chrome.extension.getURL('ost.htm'), active:false});
// active:false, so that the window do not jump to the front

ost.htm is a helper page, which creates the tab:

chrome.experimental.offscreenTabs.create({url: '...'}, function(offscreenTab) {
    // Do something with  offscreenTab.id !
});

To change the URL, use chrome.experimental.offscreenTabs.update.

offscreenTab.id is a tabId, which ought to be used with the chrome.tabs API. However, at least in Chrome 20.0.1130.1, this is not the case. All methods of the tabs API do not recognise the returned tabID.

A work-around is to inject a content script using a manifest file, eg:

{"content_scripts": {"js":["contentscript.js"], "matches":["<all_urls>"]}}
// contentscript.js:
chrome.extension.sendMessage({ .. any request .. }, function(response) {
    // Do something with response.
});

Appendum to the background page:

chrome.extension.onMessage.addListener(function(message, sender, sendResponse) {
    // Instead of checking for index == -1, you can also see if the ID matches
    // the ID of a previously created offscreenTab
    if (sender.tab && sender.tab.index === -1) {
        // index is negative if the tab is invisible
        // ... do something (logic) ...
        sendResponse( /* .. some response .. */ );
    }
});

With content scripts, you've got full access to a page's DOM. But not to the global object. You'll have to inject scripts (see this answer) if you want to run code in the context of the page.

Another API which might be useful is the chrome.webRequest API. It can be used to modify headers/abort/redirect requests. Note: It cannot be used to read or modify the response.

Currently, the offscreenTabs API is experimental. To play with it, you have to enable the experimental APIs via chrome://flags, and add "permissions":["experimental"] to your manifest file. Once it's not experimental any more, use "permissions":["offscreenTabs"].

Community
  • 1
  • 1
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • Really helpful - I've got my offscreenTab working (generally except for the the fact the toDataUrl produces an image only 1 pixel high). I am using Chromium 20.0.1132.47 and I was able to access the offscreenTab by it's id that was passed. The work-arround you proposed (appendum to background) had problems with message details (sender was undefined). All in all, a superb answer of the highest caliber. – Reinsbrain Jul 06 '12 at 15:56
  • @Reinsbrain Someone else asked a question regarding taking a screenshot. I've investigated the issue, and posted an answer (including a [full demo](http://rob.lekensteyn.nl/offscreentabs.zip)) here: [How to produce an image by chrome.experimental.offscreenTabs.toDataUrl correctly?](http://stackoverflow.com/a/11632292/938089?how-to-produce-an-image-by-chrome-experimental-offscreentabs-todataurl-correctly). – Rob W Jul 24 '12 at 13:52
  • Thanks for the heads up on that. I also had an image returning that was only 1-pixel height. Another subject that might be worth posing as a question: is there a way to evaluate (read) the DOM of the offscreenTab or is there only a screen capture of the page accessible? – Reinsbrain Jul 26 '12 at 02:54
  • @Reinsbrain Yes, that's possible. In my linked answer, I used a Content script to notify the background page using a simple `chrome.extension.sendMessage`. Within a Content Script, you've got full access to the DOM of the page, so you can read (and modify) it. If you need more details, feel free to post a new question. – Rob W Jul 26 '12 at 08:33