How to get page info from frame script in e10s-enabled Firefox?

582 Views Asked by At

I have a Firefox extension that loads page information in a function like so:

var title = content.document.title;
var url = content.document.location.href;

This function runs when a user selects a context menu item that my extension creates. Since multi-process Firefox (Electrolysis, aka e10s) doesn't support accessing the content directly, this no longer works. I'm trying to factor this code into a frame script, but I'm having problems figuring out how to "call" this code, seeing as everything seems asynchronous. Here's what I think should be my simple frame script:

// Frame script
function getPageInfo()
{
  sendSyncMessage("[email protected]:page-info-loaded", {
    pageURL : content.document.location.href,
    pageTitle : content.document.title
    });
}

addMessageListener("[email protected]:get-page-info", getPageInfo);

The relevant chrome code should look like the following, I think:

// Chrome script
function onContextItem()
{
  let browserMM = gBrowser.selectedBrowser.messageManager;
  browserMM.loadFrameScript("chrome://my-add-on/content/frame-script.js", true);
  browserMM.sendAsyncMessage("[email protected]:get-page-info");
}

function onInfoLoaded(message)
{
  var url = message.data.pageURL;
  var title = message.data.pageTitle;
  // Do something with url and title
}

gBrowser.selectedBrowser.messageManager
  .addMessageListener("[email protected]:page-info-loaded", onInfoLoaded);

The problem I'm having is that I don't fully understand if (a) this is the correct way to handle this or (b) how the timing here works out. Since this messaging system is asynchronous, I'm not guaranteed that the data I'm interested in comes back in time for me to use it. None of the examples provided by Mozilla seem to fit what I'm trying to do. Am I missing something obvious? Are there better examples anywhere showing how to convert extension code to support e10s?

1

There are 1 best solutions below

0
On

(a) this is the correct way to handle this

You should only register the frame script once, not per function call, and there's no need to set the delayed flag if you set it on a specific browser MM

You also have to remove listeners on addon shutdown and send self-destruct messages to your frame scripts, otherwise they will linger and send messages into partly-shutdown code which will probably cause buggy behavior

(b) how the timing here works out.

messages are guaranteed to be delivered and processed in order (modulo some internal high priority messages which might cut into the queue), i.e. the frame script will be added and initialized before the second message is processed.

Since this messaging system is asynchronous, I'm not guaranteed that the data I'm interested in comes back in time for me to use it.

You will have to adjust your logic to work asynchronously, waiting for the responses, just like you have no choice but to wait for an XMLHttpRequest to call its callback in normal web programming.