Skip to content
Advertisement

page_action click does not work while browser_action click works in Chrome Extension?

I want to make a simple browser extension like Font Face Ninja which toggles UI when page_action or browser_action is clicked.

The following code using browser_action works –

background.js

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

manifest.json

{
    ...
    "browser_action": {
    "default_icon": {
      "19": "icon19.png",
      "38": "icon38.png"
    }
  },
    ...
}

While the following code using page_action does not work –

background.js

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

manifest.json

{
    ...
    "page_action": {
    "default_icon": {
      "19": "icon19.png",
      "38": "icon38.png"
    }
  },
    ...
}

According to MDN docs,

Page actions are like browser actions, except that they are associated with particular web pages rather than with the browser as a whole. If an action is only relevant on certain pages, then you should use a page action and display it only on relevant pages. If an action is relevant to all pages or to the browser itself, use a browser action.

Which confirms I want to use page_action but its not working.

How do I make it work using page_action?

Advertisement

Answer

Page Action

A way to make page_action work can be found on my Github → https://github.com/deadcoder0904/insert-remove-ui-chrome-extension/tree/page_action

background.js

var hasExecutedOnce = false

function addUI(tabId) {
  chrome.tabs.sendMessage(tabId, {
    from: 'background',
    subject: 'isUIAdded?',
  })
}

chrome.runtime.onInstalled.addListener(function() {
  chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
    chrome.declarativeContent.onPageChanged.addRules([
      {
        conditions: [
          new chrome.declarativeContent.PageStateMatcher({
            pageUrl: { hostEquals: 'www.google.co.in' },
          }),
        ],
        actions: [new chrome.declarativeContent.ShowPageAction()],
      },
    ])
  })
})

chrome.pageAction.onClicked.addListener(function(tab) {
  if (!hasExecutedOnce) {
    chrome.tabs.executeScript(
      tab.id,
      {
        file: 'contentScript.js',
      },
      function() {
        addUI(tab.id)
      },
    )
    hasExecutedOnce = true
  }
  addUI(tab.id)
})

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()

Browser Action

It also has a solution for browser_action on the master branch → https://github.com/deadcoder0904/insert-remove-ui-chrome-extension/

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)
})

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()
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement