How to communicate tabs with an extension / add-on and store the variables?

6

I want to be able to communicate tabs with an extension and store values in variables and share these values between tabs, how can I do this?

  

Note: This is a tutorial question, read more at:

     
    
asked by anonymous 27.12.2017 / 16:54

1 answer

4
  

Note: link with full functional example to use / test:

     

For something to run you should use background.js in your extension and store the values, or to be more precise:

"background": {
    "scripts": [
        "background.js"
    ]
},

background works as a back-end server, it keeps running constantly, even without open tabs of a specified site in manifest.json

All tabs generated and that their pages are specified in the manifest.json can access the same execution of background.js , as there will only be one, that is, for each extension, a process that is running background.js is generated. p>

Having understood this let's go to the tabs, when the extension starts (at the start of the browser) you will be able to communicate with it, each opened new tab / window can communicate with background.js

To communicate a flap with the background you will need to use:

  • chrome.runtime.sendMessage

And to receive the request in the background you will need to use:

  • chrome.runtime.onMessage.addListener

However for this you will need to inject scripts in the pages specified in content_scripts.matches , for example, create a script called inject.js in the add-on folder and manifest.json leave something like this:

"background": {
    "scripts": [
        "background.js"
    ]
},
"content_scripts": [{
    "matches": [
        "*://superuser.com/*",
        "*://serverfault.com/*",
        "*://stackoverflow.com/*",

        "*://*.superuser.com/*",
        "*://*.serverfault.com/*",
        "*://*.stackoverflow.com/*"
    ],
    "js": [
        "inject.js"
    ]
}],
"permissions": [
    "tabs"
]

In the above example, I set the following% pages to the%:

  • will be injected into any superuser.com page (can be added to a sub-domain)
  • will be injected into any page of serverfault.com (can be added to a sub-domain)
  • will be injected into any stackoverflow.com page (can be added to a sub-domain)

Now in the contents of inject.js add this:

(function (browser) {

    var valorX = 0, valorY = 0, valorZ = 0; //Os valores vão ficar salvos nessas variaveis

    browser.runtime.onMessage.addListener(function(request, sender, sendFeedback) {

        switch (request) {
            case "acaoX":
                sendFeedback("Foi chamado a ação X");
                valorX++; //Incrementa em valorX toda vez que chamar acaoZ
                break;

            case "acaoY":
                sendFeedback("Foi chamado a ação Y");
                valorY++; //Incrementa em valorY toda vez que chamar acaoZ
                break;

            case "acaoZ":
                sendFeedback("Foi chamado a ação Z");
                valorZ++; //Incrementa em valorZ toda vez que chamar acaoZ
                break;

            //Será usado para ver na aba quantas ações de cada foram chamadas
            case "total":
                sendFeedback({
                    "x": valorX,
                    "y": valorY,
                    "z": valorZ
                });
                break;
        }
    });
})(browser||chrome); //compatibilidade para firefox e chrome

Now in background.js add this:

(function (browser) {
    function requisitarAcao(acao, callback) {
        if (browser && browser.runtime && browser.runtime.sendMessage) {
            browser.runtime.sendMessage(acao, function (response) {
                callback(response);
            });
        }
    }

    var gerado = false;

    //Cria 3 botões no final da página
    function gerarBotoes() {
        if (gerado) return; //Impede que gere mais de uma vez

        gerado = true;

        var btnX = document.createElement("button"),
            btnY = document.createElement("button"),
            btnZ = document.createElement("button"),
            btnMostrarTotal = document.createElement("button");

        btnX.textContent = "Chama ação X";
        btnY.textContent = "Chama ação Y";
        btnZ.textContent = "Chama ação Z";
        btnMostrarTotal.textContent = "Total";

        btnX.onclick = function () {
            requisitarAcao("acaoX", function (resposta) {
                alert(resposta);
            });
        };

        btnY.onclick = function () {
            requisitarAcao("acaoY", function (resposta) {
                alert(resposta);
            });
        };

        btnZ.onclick = function () {
            requisitarAcao("acaoZ", function (resposta) {
                alert(resposta);
            });
        };

        btnMostrarTotal.onclick = function () {
            requisitarAcao("total", function (resposta) {
                var totalResposta = [
                    "vezes que chamou a ação X:" + resposta.x,
                    "vezes que chamou a ação Y:" + resposta.y,
                    "vezes que chamou a ação Z:" + resposta.z
                ];

                alert(totalResposta.join("\n"));
            });
        };

        document.body.appendChild(btnX);
        document.body.appendChild(btnY);
        document.body.appendChild(btnZ);
        document.body.appendChild(btnMostrarTotal);
    }

    if (/^(interactive|complete)$/.test(document.readyState)) {
        gerarBotoes();
    } else {
        document.addEventListener("DOMContentLoaded", gerarBotoes);
        window.addEventListener("load", gerarBotoes);
    }
})(chrome||browser); //compatibilidade para firefox e chrome
  

Note: I created 3 buttons, but it's just for example, you can be anything, even a loop with inject.js , depends on what you want).

Once you have saved everything, load the extension by developer mode and open any of the sites mentioned above in setTimeout , you will notice this in their footer:

Thenclickasmanytimesasyouwantinthefirst3,theywillbeaddedtogetherandfinally,whenyougettiredclickonthebuttoncalledTotal,itwilldisplaythetotalhitsofthe3linksabove

Nowopenanewtabfromadifferentsitethanitopenedbefore,ifitopenedcontent_scripts.matchesnowopenpt.stackoverflow.com,butinsteadofclickingtheactionbuttons,clickTotaldirectly:

InmycaseIonlyclickedonceonXandonceonZ,butonthenewtabthevalueshaveremained.

Done,thiswayalltabshavethesamedataandyoucontinuewhereyouleftoff,howeveritisimportanttoknowthatifclosingthebrowseristhesameasfinalizingaserver,youwillendthebackground.jsandsothenexttimeIfyouwanttokeepthedatasavedyouwillneedtousesomethinglikesuperuser.com:

  • link
27.12.2017 / 16:54