Search code examples
javascriptcssgoogle-chrome-extensionfirefox-addon-webextensionsbrowser-extension

browser.tabs.removeCSS is not working in Chrome extension?


I want to be able to add a global CSS when I click browserAction & remove the same global css when I click browserAction again.

These are my file contents.

background.js

import browser from 'webextension-polyfill'
let hasInserted = false
const css = `* {font-family: redactedregular !important;}`

browser.browserAction.onClicked.addListener(function(tab) {
  if (!hasInserted) browser.tabs.insertCSS(tab.id, { code: css })
  else browser.tabs.removeCSS(tab.id, { code: css })
  hasInserted = !hasInserted
})

manifest.json

{
  "manifest_version": 2,
  "name": "Redact The Web",
  "offline_enabled": true,
  "version": "1.0.0",
  "description": "Extension that redacts text on the web",
  "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"]
  },
  "browser_action": {},
  "permissions": ["activeTab", "https://*/*", "http://*/*"]
}

The thing is CSS gets inserted but it doesn't get removed if I click again. How do I solve it?


Solution

  • This is technically not the answer since it's an open issue on bugs.chromium.org but I managed to make my code work using another technique @wOxxOm told above in the comments.

    I inserted CSS as a link & removed it. Here's the Gist:

    background.js

    import browser from 'webextension-polyfill'
    let hasInserted = false
    
    browser.browserAction.onClicked.addListener(function(tab) {
      browser.tabs.executeScript({ file: 'content.js' })
    
      if (!hasInserted) {
        browser.tabs.sendMessage(tab.id, {
          command: 'insertCSS',
        })
      } else {
        browser.tabs.sendMessage(tab.id, {
          command: 'removeCSS',
        })
      }
      hasInserted = !hasInserted
    })
    

    content.js

    import browser from 'webextension-polyfill'
    
    function insertCSS(file) {
      const style = document.createElement('link')
      style.rel = 'stylesheet'
      style.type = 'text/css'
      style.href = browser.extension.getURL('style.css')
      style.id = file
      document.getElementsByTagName('html')[0].appendChild(style)
    }
    
    function removeCSS(file) {
      const cssNode = document.getElementById(file)
      cssNode && cssNode.parentNode.removeChild(cssNode)
    }
    
    browser.runtime.onMessage.addListener(message => {
      const id = 'redact-the-web'
      if (message.command === 'insertCSS') {
        insertCSS(id)
      } else if (message.command === 'removeCSS') {
        removeCSS(id)
      }
    })
    

    manifest.json

    {
      "manifest_version": 2,
      "name": "Redact The Web",
      "offline_enabled": true,
      "version": "1.0.0",
      "description": "Extension that redacts text on the web",
      "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"]
      },
      "browser_action": {},
      "content_scripts": [
        {
          "matches": ["<all_urls>"],
          "js": ["content.js"],
          "run_at": "document_start"
        }
      ],
      "web_accessible_resources": ["style.css"],
      "permissions": ["https://*/*", "http://*/*"]
    }
    

    I open-sourced the whole code on GitHub → https://github.com/deadcoder0904/redact-the-web