在新的多进程 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);
}
);
亲爱的大家。
我们在我们的应用程序中为少数浏览器实施了加密签名扩展,一切顺利,但现在我们面临新 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);
}
);