diff options
author | praschke <stel@comfy.monster> | 2023-09-30 17:17:31 +0100 |
---|---|---|
committer | praschke <stel@comfy.monster> | 2023-09-30 17:56:52 +0100 |
commit | 6769ff501c8b5d20e9056de57eff5a62a92339d3 (patch) | |
tree | ee22b630a52fb802d357bb85c170c366e3f81ed7 /ext/js/background | |
parent | 0fa8d441a269b13474e6ad4108f49497d4d3abfd (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')
-rw-r--r-- | ext/js/background/backend.js | 102 |
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}; + } } |