Calling add-on from web page in new multiprocess Firefox

78 views Asked by At

dear all.

We have crypto signing extensions implemented for few browsers in our application, everything went fine, but now we faced problem with new Mozilla's multiprocess API migration (E10S aka Electrolysis).

Our web part interacts with extension which collaborates with native library written in C (we utilize c-types lib for this part).

Now Firefox is moving to multiprocess model that requires code adaptation. The most significant and complicated part for now is content-to-extension communication reimplementation. It was implemented according to related official documentation

We used bootstrap extension initialization in following manner:

function startup(params, reason) {
    include("chrome/content/extmain.js");

    mainWindow = winMediator.getMostRecentWindow("navigator:browser");
    if (null == mainWindow) {
        var windowListenerWidget = {
            onOpenWindow: function (aWindow) {
                winMediator.removeListener(windowListenerWidget);
                var mainWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                    .getInterface(Ci.nsIDOMWindow);

                mainWindow.addEventListener("load", function onWindowLoad() {
                    mainWindow.removeEventListener("load", onWindowLoad);
                    addAddonListener(mainWindow);
                });

            },
            onCloseWindow: function (aWindow) {
            },
            onWindowTitleChange: function (aWindow, aTitle) {
            }
        };
        winMediator.addListener(windowListenerWidget);
    } else {
        addAddonListener(mainWindow);
    }
}

function addAddonListener(win) {
    win.document.addEventListener(
        "CryptoApiExtension_HandleMsg",
        function (event) {
            var node = event.target;
            if (!node || node.nodeType != 3) {
                return;
            }
            var response = CryptoApiExtension.handleMessage(JSON.parse(node.nodeValue));
            var doc = node.ownerDocument;
            node.nodeValue = JSON.stringify(response);
            var event = doc.createEvent("HTMLEvents");
            event.initEvent("CryptoApiExtension_response", true, false);
            return node.dispatchEvent(event);
        }, false, true);
}

This code above was broken with new multiprocess architecture. There are lot of documentation we have read, but still there's no way we could handle this issue.

The question is: how to adapt this code to make extension accept web page invocations?

1

There are 1 answers

0
minj On BEST ANSWER

You now need to use messageManagers and frame scripts for inter-process communication:

// bootstrap.js
function addAddonListener(win) {
    win.messageManager.addEventListener(
        "CryptoApiExtension_request",
        function (event) {
            var response = CryptoApiExtension.handleRequest(event.json);
            var childMM = event.target.messageManager;
            childMM.sendAsyncMessage("CryptoApiExtension_response", response);
        }
    );
    // <...>
    win.messageManager.loadFrameScript("chrome://myaddon/content/frame-script.js", true);
}

// frame-script.js
sendAsyncMessage("CryptoApiExtension_request", request);
addMessageListener(
    "CryptoApiExtension_response",
    function(event) {
        handleResponse(event.json);
    }
);