--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -198,39 +198,49 @@ ProxyMessenger = {
// reason for having a parent process manager here.
let messageManagers = [Services.mm, Services.ppmm];
MessageChannel.addListener(messageManagers, "Extension:Connect", this);
MessageChannel.addListener(messageManagers, "Extension:Message", this);
MessageChannel.addListener(messageManagers, "Extension:Port:Disconnect", this);
MessageChannel.addListener(messageManagers, "Extension:Port:PostMessage", this);
- Services.obs.addObserver(this, "message-manager-close");
+ Services.obs.addObserver(this, "message-manager-disconnect");
this.ports = new DefaultMap(() => new Map());
},
observe(subject, topic, data) {
- if (topic === "message-manager-close") {
+ if (topic === "message-manager-disconnect") {
if (this.ports.has(subject)) {
let ports = this.ports.get(subject);
this.ports.delete(subject);
for (let [portId, {sender, recipient, receiverMM}] of ports.entries()) {
recipient.portId = portId;
MessageChannel.sendMessage(receiverMM, "Extension:Port:Disconnect", null, {
sender,
recipient,
responseType: MessageChannel.RESPONSE_TYPE_NONE,
}).catch(() => {});
}
}
}
},
+ handleEvent(event) {
+ if (event.type === "SwapDocShells") {
+ let {messageManager} = event.originalTarget;
+ if (this.ports.has(messageManager)) {
+ this.ports.set(event.detail.messageManager, this.ports.get(messageManager));
+ this.ports.delete(messageManager);
+ }
+ }
+ },
+
async receiveMessage({target, messageName, channelId, sender, recipient, data, responseType}) {
if (recipient.toNativeApp) {
let {childId, toNativeApp} = recipient;
if (messageName == "Extension:Message") {
let context = ParentAPIManager.getContextById(childId);
return new NativeApp(context, toNativeApp).sendMessage(data);
}
if (messageName == "Extension:Connect") {
@@ -263,22 +273,26 @@ ProxyMessenger = {
let promise1 = MessageChannel.sendMessage(receiverMM, messageName, data, {
sender,
recipient,
responseType,
});
if (messageName === "Extension:Connect") {
+ target.addEventListener("SwapDocShells", this, {once: true});
+
this.ports.get(target.messageManager).set(data.portId, {receiverMM, sender, recipient});
promise1.catch(() => {
this.ports.get(target.messageManager).delete(data.portId);
});
} else if (messageName === "Extension:Port:Disconnect") {
- this.ports.get(target.messageManager).delete(data.portId);
+ if (target.messageManager) {
+ this.ports.get(target.messageManager).delete(data.portId);
+ }
}
if (!(extension.isEmbedded || recipient.toProxyScript) || !extension.remote) {
return promise1;
}
// If we have a proxy script sandbox or a remote, embedded extension, where