aboutsummaryrefslogtreecommitdiff
path: root/ext/bg/js/backend.js
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2020-05-23 13:34:55 -0400
committerGitHub <noreply@github.com>2020-05-23 13:34:55 -0400
commit694120b8a5cce89101871ee58f2b7c410f909920 (patch)
tree2b6265efe30ddeb9ceb96a43200cf8e6a9653d7c /ext/bg/js/backend.js
parent9a657214ad84f031c4c642cfa64ffa6b7d71ad77 (diff)
Cross frame communication (#531)
* Set up new cross-frame port connector * Create classes for cross-frame API invocation with replies * Remove event listeners on disconnect
Diffstat (limited to 'ext/bg/js/backend.js')
-rw-r--r--ext/bg/js/backend.js40
1 files changed, 40 insertions, 0 deletions
diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js
index 20d31efc..8df4fd9d 100644
--- a/ext/bg/js/backend.js
+++ b/ext/bg/js/backend.js
@@ -163,6 +163,7 @@ class Backend {
chrome.tabs.onZoomChange.addListener(this._onZoomChange.bind(this));
}
chrome.runtime.onMessage.addListener(this.onMessage.bind(this));
+ chrome.runtime.onConnect.addListener(this._onConnect.bind(this));
const options = this.getOptions(this.optionsContext);
if (options.general.showGuide) {
@@ -236,6 +237,45 @@ class Backend {
}
}
+ _onConnect(port) {
+ try {
+ const match = /^background-cross-frame-communication-port-(\d+)$/.exec(`${port.name}`);
+ if (match === null) { return; }
+
+ const tabId = (port.sender && port.sender.tab ? port.sender.tab.id : null);
+ if (typeof tabId !== 'number') {
+ throw new Error('Port does not have an associated tab ID');
+ }
+ const senderFrameId = port.sender.frameId;
+ if (typeof tabId !== 'number') {
+ throw new Error('Port does not have an associated frame ID');
+ }
+ const targetFrameId = parseInt(match[1], 10);
+
+ let forwardPort = chrome.tabs.connect(tabId, {frameId: targetFrameId, name: `cross-frame-communication-port-${senderFrameId}`});
+
+ 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();
+ yomichan.logError(e);
+ }
+ }
+
_onClipboardText({text}) {
this._onCommandSearch({mode: 'popup', query: text});
}