2

I'm trying to make a Chrome extension which runs a script whenever the user opens a new tab.

I have the following basic code which is supposed to just paint the page red whenever the extension button is clicked.

It seems to work fine when I navigate to an actual website (ex: here on stackoverflow.com, click my extension icon, page becomes red). However, if I just create a brand new tab and click the button, the popup loads but the page never changes color.

manifest.json:

{
  "manifest_version": 2,
  "name": "ConsoleTap",
  "version": "0.1.0",
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "menu.html"
  },
  "permissions": [
    "tabs",
    "<all_urls>",
    "https://ajax.googleapis.com/"
  ]
}  

menu.html:

<!doctype html>
<html>
    <head>
        <script src="menu.js"></script>
    </head>
    <body>
        hello
    </body>
</html>

menu.js:

document.addEventListener('DOMContentLoaded', function() {
    chrome.tabs.executeScript(null,{code:"document.body.style.backgroundColor='red'"});
});  

Any ideas on why the page won't update the background color on a new tab? I'm guessing the DOMContentLoaded is never fired or it's listening after the load occurs somehow?

wOxxOm
  • 65,848
  • 11
  • 132
  • 136
Justin Maat
  • 1,965
  • 3
  • 23
  • 33

1 Answers1

5

Chrome doesn't allow content scripts on its internal pages: more info


In Chrome 60 and older it was still possible to inject content scripts into the child frames of the default new tab page because it consists of several frames so the restriction only applies to the top level frame. For the default newtab (not some newtab extension) we can match its frame url (https://www.google.com/_/chrome/newtab*) to inject a content script which will activate once a message from the popup is received:

  • manifest.json:

    {
        "name": "executeScript",
        "version": "1.0",
        "content_scripts": [{
            "matches": ["https://www.google.com/_/chrome/newtab*"],
            "js": ["newtabcontent.js"],
            "run_at": "document_start"
        }],
        "browser_action": {
            "default_icon": "icon.png",
            "default_popup": "popup.html"
        },
        "permissions": [
            "activeTab"
        ],
        "manifest_version": 2
    }
    
  • newtabcontent.js:

    chrome.runtime.onMessage.addListener(function(msg) {
        if (msg == "activate") {
            document.body.style.background = 'red';
            document.body.style.backgroundColor = 'red';
        }
    });
    
  • popup.js:

    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        if (tabs[0].url == "chrome://newtab/") {
            chrome.tabs.sendMessage(tabs[0].id, "activate");
        } else {
            chrome.tabs.executeScript({
                code: "document.body.style.backgroundColor='red'",
                allFrames: true
            });
        }
    });
    

Notes:

  1. When this extension is installed and its permissions are displayed the user will see that it can "Read and change your data on www.google.com".
  2. chrome.tabs.executeScript can't be used on newtab page because it instantly fails for the main frame due to unsupported scheme chrome:// and doesn't even proceed to execute on child frames.
wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • sorry but this doesn't seem to be working for me. The exact same code i have above with your suggested changes is still doing the exact behavior I mentioned above (popup shows but background color not changed to red) – Justin Maat Sep 27 '15 at 15:28
  • works great! "the built-in new tab page consists of several frames" - looks like I'll have to do some more reading on how the frames load and the ordering of how this all works. If you know of any documentation off-hand let me know! Thanks for your help! – Justin Maat Sep 28 '15 at 01:01
  • @JustinMaat, I don't think the newtab page layout is documented. The url I've used can be seen in devtools (F12 key): go to network panel, check "preserve log" on the top, reload the newtab page and see what's loaded. – wOxxOm Sep 28 '15 at 06:43