Search code examples
javascriptfirefox-addonfirefox-addon-sdk

Communication via postMessage()


I'm working on a Firefox extension, and I need to be able to communicate between the addon script and the content scripts. I have one direction of this working: passing the URL of a script from the addon script to a content script. However, I need to be able to go in the reverse direction, as well. My main.js file looks like this:

var data = require("self").data;
var pageMod = require("page-mod");
pageMod.PageMod({
  include: "https://trello.com/board/*",
  contentScriptWhen: 'end',
  contentScriptFile: data.url("scrumello_beta.user.js"),
  onAttach: function(worker) {
    worker.postMessage(data.url("scrumello_beta.js"));
    worker.on("message", function(addonMessage)
    {
        console.log(addonMessage);
    });
  }
});

In the client script, I have the following method:

    function OpenProcess(SCRNumber)
    {
        self.postMessage(SCRNumber); 
    }

However, when this method is called, I get the following error:

Timestamp: 8/7/2012 12:15:58 PM
Error: NS_ERROR_XPC_NOT_ENOUGH_ARGS: Not enough arguments [nsIDOMWindow.postMessage]
Source File: resource://jid0-3mulsijczmtjeuwkd5npayasqf8-at-jetpack/scogan-3/data/scrumello_beta.js
Line: 1038

This prevents the worker.on("message"... event from ever being triggered. As far as I know, postMessage only takes one argument, so any help here would be appreciated.

EDIT: I've changed the postMessage call to

self.postMessage(SCRNumber, "*"); 

I wrapped it in console.log's, both of which are being printed, so I have to assume the message is actually being posted. However, the event handler in main.js never picks up the message, because the console.log I have in there is never printed.


Solution

  • Here's how I did it. (Notice that I never used self.postmessage)

    Addon script (main.js) to content script communication:

    contentPage = pageMod.PageMod({
      onAttach: function(worker) {
    
        // Post a message directly to the content script
        worker.postMessage("any thing you want to respond");
    
        // Depending on the message, respond with different data
        worker.port.on('getFact', function() {
          worker.postMessage("any thing you want to respond");
        });
        worker.port.on('getEnabled', function() {
          worker.postMessage("any thing you want to respond");
        });
      }
    });
    

    --

    Here's the content script responding to the add-on script:

    // Get data from the addon script
    self.on('message', function(msg) {
      // Do something depending on the message passed
    });
    

    --

    Last, the content script can communicate to the add-on script like this:

    self.port.emit("message to send to add-on script")
    

    The above code will trigger the worker.port.on code in the main.js.