Search code examples
javascriptgoogle-chrome-extensionfirefox-addonbrowser-extension

Chrome extension message passing is not working?


In contentScript.js the function is not called.

background.js

var insertUI = true
// var hasExecutedOnce = false

chrome.browserAction.onClicked.addListener(function(tab) {
  console.log(`clicked browserAction`)

  // if (!hasExecutedOnce)
  chrome.tabs.executeScript(tab.id, {
    file: 'contentScript.js',
  })

  chrome.runtime.sendMessage({
    from: 'background',
    subject: insertUI ? 'insertUI' : 'removeUI',
  })

  chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (request.subject === 'doneRemovingUI') insertUI = false
    else if (request.subject === 'doneInsertingUI') insertUI = true
  })

  insertUI = !insertUI
  // hasExecutedOnce = true
})

console.log(`bg`)

manifest.json

{
  "manifest_version": 2,
  "name": "Sample",
  "version": "1.0.0",
  "description": "Sample Extension",
  "icons": {
    "16": "icon16.png",
    "19": "icon19.png",
    "24": "icon24.png",
    "32": "icon32.png",
    "38": "icon38.png",
    "48": "icon48.png",
    "64": "icon64.png",
    "128": "icon128.png"
  },
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
  "browser_action": {
    "default_icon": {
      "19": "icon19.png",
      "38": "icon38.png"
    }
  },
  "permissions": ["activeTab", "<all_urls>"]
}

contentScript.js

var body = document.getElementsByTagName('body')[0]

function insertUI() {
  console.log(`insertUI`)

  var div = document.createElement('div')
  div.setAttribute('id', 'sample-extension-12345')
  div.innerHTML = `<h1>Sample Extension</h1>`
  body.appendChild(div)
}

function removeUI() {
  console.log(`removeUI`)

  var divId = document.getElementById('sample-extension-12345')
  body.removeChild(divId)
}

function main() {
  console.log(`main called`)

  chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
    console.log({ msg, sender, sendResponse })

    if (msg.subject === 'insertUI') {
      insertUI()
      sendResponse({
        from: 'content',
        subject: 'doneInsertingUI',
      })
    } else if (msg.subject === 'removeUI') {
      removeUI()
      sendResponse({
        from: 'content',
        subject: 'doneRemovingUI',
      })
    }
  })
}
console.log(`contentScript`)

main()

So everything works. insertUI() & removeUI() works individually in contentScript.js but the chrome.runtime.onMessage.addListener is never called.

The console.log() in it are not called. Rest everything works. Inserting in DOM & removing DOM works separately. They just need to work when browser_action is toggled.


Solution

  • Iván Nokonoko answered the problem above in comments. Posting it here for brevity -

    background.js

    var hasExecutedOnce = false
    
    function addUI(tabId) {
      chrome.tabs.sendMessage(tabId, {
        from: 'background',
        subject: 'isUIAdded?',
      })
    }
    
    chrome.browserAction.onClicked.addListener(function(tab) {
      if (!hasExecutedOnce) {
        chrome.tabs.executeScript(
          tab.id,
          {
            file: 'contentScript.js',
          },
          function() {
            addUI(tab.id)
          },
        )
        hasExecutedOnce = true
      }
      addUI(tab.id)
    })
    

    manifest.json

    {
      "manifest_version": 2,
      "name": "Sample",
      "version": "1.0.0",
      "description": "Sample Extension",
      "icons": {
        "16": "icon16.png",
        "19": "icon19.png",
        "24": "icon24.png",
        "32": "icon32.png",
        "38": "icon38.png",
        "48": "icon48.png",
        "64": "icon64.png",
        "128": "icon128.png"
      },
      "background": {
        "scripts": ["background.js"],
        "persistent": false
      },
      "browser_action": {
        "default_icon": {
          "19": "icon19.png",
          "38": "icon38.png"
        }
      },
      "permissions": ["activeTab", "<all_urls>"]
    }
    

    contentScript.js

    var body = document.getElementsByTagName('body')[0]
    
    function insertUI() {
      var div = document.createElement('div')
      div.setAttribute('id', 'sample-extension-12345')
      div.innerHTML = `<h1>Sample Extension</h1>`
      body.appendChild(div)
    }
    
    function removeUI() {
      document.getElementById('sample-extension-12345').remove()
    }
    
    function main() {
      chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
        if (request.subject === 'isUIAdded?') {
          const id = document.getElementById('sample-extension-12345')
          if (id === null) insertUI()
          else removeUI()
        }
      })
    }
    
    main()