14

I'm using the example from the Google tutorial and finding it difficult to pass a simple message to the content script from the popup.

Can you provide some suggestions on how to pass a simple message and view it either in the console log or alert?

manifest.json

{
  "manifest_version": 2,

  "name": "msg-test",
  "description": "message test",
  "version": "1.0",

  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },

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

  "content_scripts": [{
     "matches": ["http://*/*","http://www.site.com/*"],
     "js": ["content.js"],
     "run_at": "document_end"
  }],  

  "permissions": [
    "tabs",
    "http://*/*"
  ]  
}

background.js

chrome.runtime.onConnect.addListener(function(port){
  port.postMessage({greeting:"hello"});
});

content.js

var port = chrome.runtime.connect({name:"content"});
port.onMessage.addListener(function(message,sender){
  if(message.greeting === "hello"){
    alert(message.greeting);
  }
});

popup.js

window.onload = function() {

    document.getElementById('btn2').onclick = function() {
       alert("button 2 was clicked");
     }; 

    document.getElementById('btn1').onclick = function() {
        alert("button 1 was clicked");
     }; 


}

*Note: In this example the content script will fire when the page matches manifest.json and the alert box will show.

rrrfusco
  • 1,099
  • 5
  • 19
  • 46
  • @aclave1 Could you please introduce all files of your extension in question, I want to try myself. The other files (such as popup.html) did not explicitly determined in developer.chrome.com/extensions/messaging – Hosein Aqajani Nov 21 '15 at 11:50

1 Answers1

29

First, I wouldn't message pass between your popup and your content script. I would message pass between your Background page and your content scripts. Your popup page should only be used to show some ui to interact with your app.

With that being said, I will show you the way to pass messages between your background and your content script.

In your content script:

//This line opens up a long-lived connection to your background page.
var port = chrome.runtime.connect({name:"mycontentscript"});
port.onMessage.addListener(function(message,sender){
  if(message.greeting === "hello"){
    alert(message.greeting);
  }
});

In your background page(possibly your popup? but I don't recommend it)

chrome.runtime.onConnect.addListener(function(port){
  port.postMessage({greeting:"hello"});
});

Here is the sequence of events that will take place:

  1. Your application will inject your content script into the page
  2. Your content script will open up a port to communicate with the background script.
  3. Your background script will be notified that a port was open, allowing it to send a message to it, or attach a message listener to it.

In the background script or the content script, you can listen for messages by using port.onMessage.addListener(). provided that port is in scope. Using ports is much easier to grasp and allows for simple, two way communication!

Edit:

If you would like to pass messages to your background page from your popup script, use the exact same method:

var port   =   chrome.runtime.connect({name: "popup-port"});
port.postMessage({status:"poppedup"});

Edit 2:

To navigate your user to a new page, do this:

function navigateToPage(url){
    chrome.tabs.query({url: url}, function(tabs) {
        var tab = tabs[0];
        return tab ? chrome.tabs.update(tab.id, {active:true}) : chrome.tabs.create({url: url});
    });
}
});

What this function does is, it checks to see if there is a tab with the url you want to go to, if there is, switch to it, else, create a tab with that url and navigate to it.

aclave1
  • 1,680
  • 18
  • 29
  • 1
    popup.js is considered a "Dumb view": "In a typical extension with a background page, the UI — for example, the browser action or page action and any options page — is implemented by dumb views. When the view needs some state, it requests the state from the background page. When the background page notices a state change, the background page tells the views to update." – aclave1 Feb 14 '14 at 17:53
  • You can add a background page by adding this to your manifest: "background": { "page": "background.html", "persistent": true }, – aclave1 Feb 14 '14 at 18:00
  • No, but that's not message passing. You don't even need a content script to change the url of the current tab. I will edit my answer to show you how to do that. – aclave1 Feb 14 '14 at 20:37
  • 2
    After spending 2 hours fruitlessly looking through the official docs, THIS actually helps me accomplish what I wanted to. THANK YOU – Augie Gardner Jun 22 '18 at 22:52