Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to interact with background.js from the popup?

Is there any way to pass information between the popup.html (or popup.js) and a background script?

I'd like the popup to display information from a user's account or allow them to log in, but have the background.js handle the authentication and other logic. I have background.js declared in the manifest, but there seems to be no indication that it's being used at all.

Edit: If I'm going about this all wrong and there's a better way to do this, that would be great too.

like image 212
Kelly Behr Avatar asked Mar 02 '12 17:03

Kelly Behr


3 Answers

Note that the background page and the popup live in the same process (the extension process), so one page can get the DOM window of the other and then call functions or set variables directly. For example, the popup can call chrome.extension.getBackgroundPage to modify the background:

chrome.extension.getBackgroundPage().variable = 42;

and the background page can call chrome.extension.getViews to get the popup:

var popups = chrome.extension.getViews({type: "popup"});
if (0 < popups.length)
  popups[0].variable = 42;

Another way to set shared variables is by using traditional DOM APIs, since each extension gets a fake origin (such as "eakjnniffhfegdpfehmnpcmjiameincp"). So when you modify localStorage, document.cookie, or IndexedDB on the background, it can be read back in the popup.

That said, you may still want to use the message passing APIs even within pages in the extension process, since it may make your code more uniform. Message passing is the only way to communcate with content scripts.

like image 77
yonran Avatar answered Sep 30 '22 20:09

yonran


Use the chrome.extension API.

You can send requests back and forth or even better use a port for continuous communication.

The example I give will create a two way communication between the popup and background page that connect when the popup is opened up.

Just create a socket.js file that is included in both the background page and the popup page. Then on each you can just declare:

new Socket();

Here is the implementation of socket.js:

var Socket = function() {
    window.socket = this;

    this.port = chrome.extension.connect({name:"popupToBackground"});

    chrome.extension.onConnect.addListener(function(port) {
        if(port.name == "backgroundToPopup") {}
            else if(port.name == "popupToBackground") {
            window.socket.port = chrome.extension.connect({name:"backgroundToPopup"});
        }
        else {
            return;
        }

        port.onMessage.addListener(function(msg) {
            try {
                window[msg.namespace][msg.literal][msg.method].apply(this, msg.args);
            }
            catch(error) {
                // your failed action goes here.
            }
        });
    });
};

Make sure you make the generic method calls in the message listener work for you. I like the format I have given above - it is very robust. To send messages back and forth just post them to the socket:

socket.post({ namespace: "myNamespace",
              literal: "myLiteral",
              method: "myMethod",
              args: ["argOne", "argTwo"]
           });
});

So if this were executed from the popup page then the background page would call:

window.myNamespace.myLiteral.myMethod(argOne, argTwo);

To me this is a very nice reusable javascript object. You can even add specific prototype functions if you would like - this way its even easier to send messages:

Socket.prototype = {
    sendOneTwo: function() {
        socket.post({ namespace: "myNamespace",
                      literal: "myLiteral",
                      method: "myMethod",
                      args: ["argOne", "argTwo"]
    });
};

Now all you have to say is:

socket.sendOneTwo();
like image 37
jjNford Avatar answered Sep 30 '22 19:09

jjNford


For just debugging purposes I find this pretty handy in popup JS:

console = chrome.extension.getBackgroundPage().console
like image 43
PETER BROWN Avatar answered Sep 30 '22 20:09

PETER BROWN