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