Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do i toggle on/off content_scripts in a google extension?

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.

like image 357
razz Avatar asked Oct 21 '22 07:10

razz


2 Answers

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.

like image 91
razz Avatar answered Oct 23 '22 23:10

razz


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.

like image 36
Jude Osborn Avatar answered Oct 23 '22 21:10

Jude Osborn