4

I've already read the documentation from Google on 'message passing' a few times and have probably looked at over 10 other questions with the same problem and already tried quiet a few variations of most of their "solutions" and of what I have below... This is black magic, right? Either way, here it goes.

Manifest File:

{
    "manifest_version" : 2,
    "name" : "Message Test",
    "version" : "1.0",

    "browser_action": { 
        "default_popup": "popup.html"
    },

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

    "content_scripts": [
        {
        "matches" : ["<all_urls>"],
        "js": ["message-test.js"]
        }
    ]    
}

I'm aware extensions aren't suppose to use inline JS, but I'm leaving this in so the original question can be left as it was since I still can't get the message to send from the background page, When I switch from the popup to the background, I removed the appropriate lines from the manifest.json

popup.html file:

<html>
  <head>
    <script>
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
      chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello", theMessage: "Why isn\'t this working?"}, function(response) {
        console.log(response.farewell);
      });
    });
    </script>
  </head>
<body>
</body>
</html>

OR

background.js file:

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
  chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello", theMessage: "Why isn\'t this working?"}, function(response) {
    console.log(response.farewell);
  });
});

message-test.js file:

var Mymessage;
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
    if (message.greeting == "hello"){
        Mymessage = message.theMessage;
        alert(Mymessage);
    }
    else{
        sendResponse({});
    }
});

I get an undefined alert...

I'm also trying to execute this after pressing a button from a popup and having a window at a specified url, but that's a later issue. The other files for the button and window can be found here except with the background.js content wrapped in an addEventListener("click"....: http://pastebin.com/KhqxLx5y AND http://pastebin.com/JaGcp6tj

user3334776
  • 113
  • 1
  • 10
  • all_urls is not valid syntax – Zig Mandel Apr 17 '14 at 01:28
  • @ZigMandel It so happens it is. – Xan Apr 17 '14 at 08:36
  • @hucuhy thanks for putting this bounty out on the question. I still haven't received a helpful response since posting this as of today (which is June 3, 2014). Being able to send a message from the background page to a content script after clicking a button from the default popup wouldn't seem too hard for people who know how this stuff works... – user3334776 Jun 03 '14 at 20:45

3 Answers3

3

There are several issues in your code.

Chrome doesn't allow inline scripts in extensions. You must divide your popup.html to script + HTML:

// popup.html
<html>
<body>
<script type="text/javascript" src="popup.js"></script>
</body>
</html>

// popup.js
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    var tab = tabs[0];  // do not forget to declare "tab" variable
    chrome.tabs.sendMessage(tab.id, {
        greeting: "Can you hear me?"
    }, function(response){});
});
KAdot
  • 1,997
  • 13
  • 21
  • To add to this answer, you could've caught the errors if you inspected the popup's Developer Console, by right-clicking your button and selecting "Inspect popup". – Xan Apr 17 '14 at 08:39
  • "activeTab" is not needed, because the popup is communicating with an existing content script, it's not trying to insert a new one. – Rob W Apr 17 '14 at 09:30
  • So I tried it verbatim, it still doesn't work... The exact same "manifest.json" file, the same "message-test.js" file... I copied and pasted your popup.html and your popup.js. No alert goes off. – user3334776 Apr 17 '14 at 21:52
  • Do any of you know what else I should try with this? – user3334776 Apr 19 '14 at 03:16
  • @user3334776 Did you properly reload your extension after making the changes, AND reloaded pages you're testing for the new content script to be injected? – Xan Apr 22 '14 at 08:08
  • Have you tried running Chrome with logging enabled? see here -http://www.chromium.org/for-testers/enable-logging – FuzzyAmi May 31 '14 at 18:59
2

Careful reading of this answer may help you. Every point there applies to your problem.

Your problem is in when your main script is executing, and when your content scripts are. You need to ensure there is a content script listening before you send a message to it, in worst case injecting it programmatically.

And to get it working in a popup, follow KAdot's answer.

Community
  • 1
  • 1
Xan
  • 74,770
  • 16
  • 179
  • 206
-1

Here is the solution, using background script:

manifest.json

{
    "manifest_version" : 2,
    "name" : "Message Test",
    "version" : "1.0",

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

    "content_scripts": [
        {
        "matches" : ["<all_urls>"],
        "js": ["message-test.js"]
        }
    ]
}

message-test.js

var port = chrome.runtime.connect();
port.onMessage.addListener(function(message, sender, sendResponse) {
    if (message.greeting == "Can you hear me?"){
        alert("Test");
    }
    else{
        sendResponse({});
    }
});

popup.js

chrome.runtime.onConnect.addListener( function ( port ) {
port.postMessage({
        greeting: "Can you hear me?"
    });
});

Some explanaition: first we are connecting to our background script from content script and then background script sends message to content script.

Update

I've improved answer according to @Xan remark. But the idea is the same, first of all you should let know your background script of the existence of content script.

dIsoVi
  • 869
  • 7
  • 14
  • Using opening a port for just knocking just feels.. wrong. – Xan May 27 '14 at 08:58
  • @Xan sorry what?)do you know any other way to communicate wtih background scripts?) – dIsoVi May 27 '14 at 09:04
  • Why use `chrome.runtime.connect` / `chrome.runtime.onConnect` if you're not using the resulting port? – Xan May 27 '14 at 09:06
  • I'm using runtime connect to connect to background script, until that background script knows nothing about content script. – dIsoVi May 27 '14 at 09:06
  • **Wrong**. You can use either `connect` / `onConnect` and work through a port, or `sendMessage` / `onMessage` and work with it. There's no need to open and immediately discard a port. – Xan May 27 '14 at 09:08
  • yes you can use sendMessage, but it is the same things, sendMessage is a shortcut I suppose. From documentation https://developer.chrome.com/extensions/runtime#method-sendMessage Sendmessage - similar to runtime.connect but only sends a single message, with an optional response. So you can replace connect with sendMessage, but what for? – dIsoVi May 27 '14 at 09:17
  • My point is - if you're opening a port, use it. But it's just a quirk, your solution is not wrong. – Xan May 27 '14 at 09:20
  • @Xan I've improved answer according to our discussion. I've just wanted to show what was wrong, using the code provided by the question owner) – dIsoVi May 27 '14 at 09:33
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/54509/discussion-between-xan-and-disovi). – Xan May 27 '14 at 09:33
  • OP states 'I need to message from the popup either way', so this is not a solution to their needs. KAdot's answer works just fine. Besides, using 'popup.js' as the name of a background script just adds confusion. – rsanchez May 27 '14 at 09:45
  • @dIsoVi Out of all of the responses, yours is working the best, thank you. I'm still having trouble getting this to execute when I click a button from a default popup instead of having the message sent every time I load a page (I only need this to execute once for the whole extension). The modified version of the background script I tried can be found here: http://pastebin.com/87qRzcck The modified version of the manifest is here: http://pastebin.com/7AahdqPf and the default popup.html can be found here: http://pastebin.com/ybVNxLpA Could you take another whack at this? – user3334776 Jun 04 '14 at 02:15