Nicholas Rubin
Nicholas Rubin

Reputation: 327

Chrome content script run in all pages in a given tab

I have a Chrome extension (content script) with a popup window. When the user clicks a "Start" button in the popup window, I'd like a new tab to open to a url (say www.test.com), and for the content script to be injected into that tab. Not just executed once, but injected so that it will work on (www.test.com/*) on that same tab. Not in other tabs - just that one.

Here's what I have now:

chrome.tabs.create({
        'url': 'http://test.com/shop/new'
        }, function(tab) {
        chrome.tabs.executeScript(tab.id, {
            'file': 'script.js'
        });
    });

But, chrome.tabs.executeScript is being used, which only executes the script once. The script redirects the page to 'http://test.com/shop/new/xxx', but since the script is only executed once, it stops working when the page changes. Again - how can I make it so that the script is injected into all 'http://test.com/shop/*' pages in that tab?

Upvotes: 0

Views: 2013

Answers (1)

Xan
Xan

Reputation: 77541

A good idea is to make a script that is always injected into http://test.com/shop/* (via manifest):

  "content_scripts" : [
    {
      matches: ["http://test.com/shop/*"],
      js: ["script.js"]
    }
  ],

Then, in the script, ask the background page if it should be active for this ID:

// script.js
chrome.runtime.sendMessage({shouldIRun : true}, function(response){
  if(response) {
    // Actually do stuff
  }
});

And in the background script, keep a record of tabs that you want it to apply to:

// Background script
var activeTabs = {}; // Slightly more difficult with event pages

// At some point when you enable it, e.g. in a browserAction.onClicked listener
activeTabs[tabId] = true;

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
  if(message.shouldIRun) {
    // Double negation to ensure true/false
    sendResponse(!!activeTabs[sender.tab.id]);
  }
});

// It's a good idea to clear the stray entries
chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) {
  delete activeTabs[tabId];
});

// Sometimes this can also happen
chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId) {
  if(!!activeTabs[removedTabId]) activeTabs[addedTabId] = true;
  delete activeTabs[removedTabId];
});    

Upvotes: 1

Related Questions