aboutsummaryrefslogtreecommitdiff
path: root/ext/js/background/backend.js
diff options
context:
space:
mode:
authorpraschke <stel@comfy.monster>2023-09-30 17:17:31 +0100
committerpraschke <stel@comfy.monster>2023-09-30 17:56:52 +0100
commit6769ff501c8b5d20e9056de57eff5a62a92339d3 (patch)
treeee22b630a52fb802d357bb85c170c366e3f81ed7 /ext/js/background/backend.js
parent0fa8d441a269b13474e6ad4108f49497d4d3abfd (diff)
create both cross-frame ports in the background
on Chrome (currently 117), the port created in the content script with runtime.connect does not properly receive an onDisconnect event when the service worker sleeps. the port created in the background with tabs.connect does receive the event, so create both ports with tabs.connect. fixes #241.
Diffstat (limited to 'ext/js/background/backend.js')
-rw-r--r--ext/js/background/backend.js102
1 files changed, 46 insertions, 56 deletions
diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js
index dd233abb..3cac2e4d 100644
--- a/ext/js/background/backend.js
+++ b/ext/js/background/backend.js
@@ -139,7 +139,8 @@ class Backend {
['textHasJapaneseCharacters', {async: false, contentScript: true, handler: this._onApiTextHasJapaneseCharacters.bind(this)}],
['getTermFrequencies', {async: true, contentScript: true, handler: this._onApiGetTermFrequencies.bind(this)}],
['findAnkiNotes', {async: true, contentScript: true, handler: this._onApiFindAnkiNotes.bind(this)}],
- ['loadExtensionScripts', {async: true, contentScript: true, handler: this._onApiLoadExtensionScripts.bind(this)}]
+ ['loadExtensionScripts', {async: true, contentScript: true, handler: this._onApiLoadExtensionScripts.bind(this)}],
+ ['openCrossFramePort', {async: false, contentScript: true, handler: this._onApiOpenCrossFramePort.bind(this)}]
]);
this._messageHandlersWithProgress = new Map([
]);
@@ -189,9 +190,6 @@ class Backend {
chrome.tabs.onZoomChange.addListener(onZoomChange);
}
- const onConnect = this._onWebExtensionEventWrapper(this._onConnect.bind(this));
- chrome.runtime.onConnect.addListener(onConnect);
-
const onMessage = this._onMessageWrapper.bind(this);
chrome.runtime.onMessage.addListener(onMessage);
@@ -331,58 +329,6 @@ class Backend {
return invokeMessageHandler(messageHandler, params, callback, sender);
}
- _onConnect(port) {
- try {
- let details;
- try {
- details = JSON.parse(port.name);
- } catch (e) {
- return;
- }
- if (details.name !== 'background-cross-frame-communication-port') { return; }
-
- const senderTabId = (port.sender && port.sender.tab ? port.sender.tab.id : null);
- if (typeof senderTabId !== 'number') {
- throw new Error('Port does not have an associated tab ID');
- }
- const senderFrameId = port.sender.frameId;
- if (typeof senderFrameId !== 'number') {
- throw new Error('Port does not have an associated frame ID');
- }
- let {targetTabId, targetFrameId} = details;
- if (typeof targetTabId !== 'number') {
- targetTabId = senderTabId;
- }
-
- const details2 = {
- name: 'cross-frame-communication-port',
- sourceTabId: senderTabId,
- sourceFrameId: senderFrameId
- };
- let forwardPort = chrome.tabs.connect(targetTabId, {frameId: targetFrameId, name: JSON.stringify(details2)});
-
- const cleanup = () => {
- this._checkLastError(chrome.runtime.lastError);
- if (forwardPort !== null) {
- forwardPort.disconnect();
- forwardPort = null;
- }
- if (port !== null) {
- port.disconnect();
- port = null;
- }
- };
-
- port.onMessage.addListener((message) => { forwardPort.postMessage(message); });
- forwardPort.onMessage.addListener((message) => { port.postMessage(message); });
- port.onDisconnect.addListener(cleanup);
- forwardPort.onDisconnect.addListener(cleanup);
- } catch (e) {
- port.disconnect();
- log.error(e);
- }
- }
-
_onZoomChange({tabId, oldZoomFactor, newZoomFactor}) {
this._sendMessageTabIgnoreResponse(tabId, {action: 'Yomichan.zoomChanged', params: {oldZoomFactor, newZoomFactor}});
}
@@ -2273,4 +2219,48 @@ class Backend {
}
return results;
}
+
+ _onApiOpenCrossFramePort({targetTabId, targetFrameId}, sender) {
+ const sourceTabId = (sender && sender.tab ? sender.tab.id : null);
+ if (typeof sourceTabId !== 'number') {
+ throw new Error('Port does not have an associated tab ID');
+ }
+ const sourceFrameId = sender.frameId;
+ if (typeof sourceFrameId !== 'number') {
+ throw new Error('Port does not have an associated frame ID');
+ }
+
+ const sourceDetails = {
+ name: 'cross-frame-communication-port',
+ otherTabId: targetTabId,
+ otherFrameId: targetFrameId
+ };
+ const targetDetails = {
+ name: 'cross-frame-communication-port',
+ otherTabId: sourceTabId,
+ otherFrameId: sourceFrameId
+ };
+ let sourcePort = chrome.tabs.connect(sourceTabId, {frameId: sourceFrameId, name: JSON.stringify(sourceDetails)});
+ let targetPort = chrome.tabs.connect(targetTabId, {frameId: targetFrameId, name: JSON.stringify(targetDetails)});
+
+ const cleanup = () => {
+ console.log('cross-frame cleanup', targetPort, sourcePort);
+ this._checkLastError(chrome.runtime.lastError);
+ if (targetPort !== null) {
+ targetPort.disconnect();
+ targetPort = null;
+ }
+ if (sourcePort !== null) {
+ sourcePort.disconnect();
+ sourcePort = null;
+ }
+ };
+
+ sourcePort.onMessage.addListener((message) => { targetPort.postMessage(message); });
+ targetPort.onMessage.addListener((message) => { sourcePort.postMessage(message); });
+ sourcePort.onDisconnect.addListener(cleanup);
+ targetPort.onDisconnect.addListener(cleanup);
+
+ return {targetTabId, targetFrameId};
+ }
}