1

I'm working on my first Chrome extension. It's a (theoretically) simple extension, which just does one thing: On tab opening (without clicking the extension icon), it's supposed to look at the page DOM, and hide a particular div.

From some articles on Stack Overflow, I decided on a pattern:

  1. In manifest.json, point to a main background file (main.js), and define another file (content.js) as one of the content_scripts.
  2. In main.js, on tab creation, send a message to the content.js script, passing a callback to be run with the page content.
  3. In content.js, listen for the message, and on the message, hide the div in the page.

Unfortunately, that third step doesn't seem to run at all (so neither does the callback in the message send). I haven't been able to figure out why, but it appears the code just isn't running. I've looked around on Stack Overflow quite a bit (here's a recent search), and haven't been able to figure out what's not working.

Would appreciate your thoughts/ideas.

Here's my current code:

Note, I haven't been able to figure out a good debugging setup. Added The Chrome Apps & Extensions Developer tool, but it doesn't seem to let me use debuggers or view console logs, so I'm just alerting, currently. If you have suggestions here, they'd be much appreciated as well.

manifest.json

{
  "manifest_version": 2,
  "name": "Inertia",
  "description": "My fun chrome extension!",
  "version": "1.0",
  "background": {
    "scripts": ["main.js"]
  },
  "content_scripts": [{
    "matches": ["<all_urls>"],
    "js": ["content.js"]
  }],
  "browser_action": {
    "default_icon": "icon.png"
  },
  "permissions": ["tabs"]
}

main.js

chrome.tabs.onCreated.addListener(function(tab) {
    alert('above send')
    alert(JSON.stringify(tab))
    chrome.tabs.sendMessage({ Message: 'hideCenter' }, function (doc) {
      alert('in callback')
      alert(doc)
      alert(doc.innerHTML)
      const center = doc.getElementById('center');
      if (center) {
        alert('found center');
        center.style.display = 'none';
        center.style.opacity = '0';
        alert(center)
      } else {
        alert('woops');
      }
    });
});

content.js

alert('above message listener');
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  alert('runtime');
  alert(JSON.stringify(request))

  if (request.Message === 'hideCenter') {
    alert('message text');
    alert(document.all[0].outerHTML);
    sendResponse(document);
  } else {
    alert('different message');
    alert(request.Message)
  }
})

Of all the alerts, only two show up: above send and the JSON.stringify(tab) below it, which logs a JSON object that looks like I suspect it should.

Any idea what I'm doing wrong here, and how to hook these things together correctly? Thanks!

EDIT in response to feedback from @wOxxOm:

I added tab.id as the first argument to sendMessage. I had that before, but changed it in response to the accepted answer on this question.

At any rate, when I add that back, opening a new tab now hits the alert within the callback! But doc is undefined, so it breaks on doc.innerHTML. It seems to work when following a link (ie, opening a new page with content) -- hitting all the alerts including in the listener, and successfully logging the page content.

I'm going to continue playing with this, cause my suspicion is that I have to wait until my current new-tab extension adds content to the page (I'm trying to build this on top of that extension, and alter the content it adds), but if anyone has any idea of why the new tab doesn't have a document object, please let me know.

Sasha
  • 6,224
  • 10
  • 55
  • 102
  • 4
    1. Always check the documentation for method signatures: tabs.sendMessage first param should be `tab.id`. 2. [debugging background page](https://stackoverflow.com/a/10258029) 3. debugging [content scripts](https://stackoverflow.com/a/21734890) (or [this](https://stackoverflow.com/a/17120590)). You can easily find the basic stuff by simply googling for like "how to debug chrome extension background page" etc. – wOxxOm Jul 18 '17 at 18:23
  • 1
    `sendResponse(document);` won't work. Messages *must be* JSON-ifiable. DOM nodes are not JSON-ifiable. You appear to be trying to send the document back to the background page. That can't work. You could send the HTML, but should not. Process the DOM in the content script and only send back the information you need. – Makyen Jul 19 '17 at 13:50
  • @Makyen -- If I don't want information from the page, but I instead want to do something with the (section of the) DOM, how would that work? Is that possible? – Sasha Jul 19 '17 at 17:55
  • 1
    If you want to manipulate the page, then that has to happen in the content script. It can't happen in the background script. You can pass information back and forth between the two contexts, but that information must be JSON-ifiable. – Makyen Jul 19 '17 at 18:11

0 Answers0