Reputation: 10110
I have this simple extension, it displays icon on chrome's toolbar and shows a enable/disable button. i want to add function to the button to disable or enable the content_script.js
which fires on visiting google website:
popup.js
var setLayout = function(){
var list = document.createElement('ul');
var enable = document.createElement('li');
enable.appendChild(document.createTextNode('Enable Script'));
enable.onclick = function(){toggle(0)};
var disable = document.createElement('li');
disable.appendChild(document.createTextNode('Disable Script'));
disable.onclick = function(){toggle(1)};
list.appendChild(disable);
document.body.appendChild(list);
function toggle(n){
list.removeChild( n == 0 ? enable : disable);
list.appendChild(n == 0 ? disable : enable);
}
};
document.addEventListener('DOMContentLoaded', setLayout, false);
manifest.json
{
"manifest_version": 2,
"name": "test",
"description": "test",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": ["https://www.google.co.uk/"],
"js": ["content_scripts.js"]
}
]
}
content_scripts.js
(function(){
alert('hello');
})();
i'm new to google extensions and have no idea how to do that, i thought about changing the manifist after clicking disable/enable buttons but couldn't find the right command to do so after reading the documentations on google website!
any help would be greately appreciated.
Upvotes: 5
Views: 4596
Reputation: 10110
After some research i figured out how to solve this by using backround pages
, sendMessage
and localstorage
.
background pages
work as a communicator between popup.js
and content_scripts.js
, they are on two different documents and it's not possible to pass variables between them directly.
To enable background page in mamifest i added:
"background": {
"scripts": ["background.js"],
"persistent": true
},
localstorage
save variables locally and remember them even when the browser is closed and opened again, so when enable/disable button is clicked it set localStorage['status'] = 1/0
which can be accessed through background.js
and passed to content_scripts.js
.
To set localStorage variable i added to popup.js
:
if(!localStorage.status) localStorage['status'] = 1;
toggle(2);
enable.onclick = function(){toggle(0)};
disable.onclick = function(){toggle(1)};
function toggle(n){
if((n == 0) && (enable.parentNode == list)){
list.removeChild(enable);
list.appendChild(disable);
localStorage.status = 1;
}else if((n == 1) && (disable.parentNode == list)){
list.removeChild(disable);
list.appendChild(enable);
localStorage.status = 0;
}else if((n == 2) && (!list.hasChildNodes())){
list.appendChild((localStorage.status == 1) ? disable : enable);
chrome.browserAction.setIcon({path: (localStorage.status == 1) ? "icons/icon19.png" : "icons/icon19_disabled.png"});
}else{
return;
}
}
To pass localStorage.status
to content_scripts.js
i had to use sendMessage
on content_scrips.js
which on loaded send request message to background.js
, and onMessage
on background.js
which listens to requests and send response to content_scripts.js
with the localStorage.status
value.
background.js:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.type == "status") sendResponse({status: localStorage.status});
});
content_scripts.js
var fn = function(){...};
chrome.runtime.sendMessage({type: "status"}, function(response) {
if(response.status == 1) fn();
return;
});
That's it, hope someone find it useful.
Upvotes: 2
Reputation: 1798
Try injecting the content script using code rather than the manifest file, something like this:
chrome.tabs.executeScript(null, {file: "content_script.js"});
You can then use message passing between the background page and your content script to decide whether or not to inject the content script, or perhaps an if statement in the content script itself that only runs when a flag set by the extension's action button.
You can use a browser action event to detect when the action button is pressed.
Upvotes: 1