在新的多进程 Firefox 中从网页调用附加组件

Calling add-on from web page in new multiprocess Firefox

亲爱的大家。

我们在我们的应用程序中为少数浏览器实施了加密签名扩展,一切顺利,但现在我们面临新 Mozilla 的多进程 API 迁移(E10S 又名电解)的问题。

我们的 Web 部件与扩展交互,扩展与用 C 编写的本机库协作(我们在这部分使用 c-types 库)。

现在 Firefox 正在转向需要代码适配的多进程模型。目前最重要和最复杂的部分是内容到扩展通信的重新实现。根据相关官方执行documentation

我们按以下方式使用 bootstrap 扩展初始化:

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);
}

上面的代码已被新的多进程架构破坏。我们已经阅读了很多文档,但仍然无法解决这个问题。

问题是:如何调整此代码以使扩展程序接受网页调用?

您现在需要使用 messageManagers and frame scripts 进行 inter-process 通信:

// 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);
    }
);