diff options
author | Wojtek Kosior <koszko@koszko.org> | 2021-12-27 16:55:28 +0100 |
---|---|---|
committer | Wojtek Kosior <koszko@koszko.org> | 2021-12-27 16:55:28 +0100 |
commit | 01e977f922ea29cd2994f96c18e4b3f033b1802d (patch) | |
tree | 0c5b3ceb13bf364c209ef097644d81e6e04ea91d /common/message_server.js | |
parent | b590eaa2f64ead3384eadc6fe58f6358aa1a0478 (diff) | |
download | browser-extension-01e977f922ea29cd2994f96c18e4b3f033b1802d.tar.gz browser-extension-01e977f922ea29cd2994f96c18e4b3f033b1802d.zip |
facilitate egistering dynamic content scripts with mappings data
Diffstat (limited to 'common/message_server.js')
-rw-r--r-- | common/message_server.js | 61 |
1 files changed, 53 insertions, 8 deletions
diff --git a/common/message_server.js b/common/message_server.js index fd609c7..657e140 100644 --- a/common/message_server.js +++ b/common/message_server.js @@ -43,23 +43,68 @@ #FROM common/browser.js IMPORT browser -var listeners = {}; +let listeners = {}; +let listening = false; -/* magic should be one of the constants from /common/connection_types.js */ +function raw_listen(port) +{ + if (listeners[port.name] === undefined) + return; + + listeners[port.name](port); +} +/* magic should be one of the constants from /common/connection_types.js */ function listen_for_connection(magic, cb) { + if (!listening) { + listening = true; + browser.runtime.onConnect.addListener(raw_listen); + } listeners[magic] = cb; } +#EXPORT listen_for_connection -function raw_listen(port) +/* + * Messaging background page from itself might result in messages being silently + * discarded. Here we implement an interface (somewhat) compatible with the one + * provided by the browser, but which allows for background page to communicate + * with itself. + */ +function EvTarget() { - if (listeners[port.name] === undefined) - return; + this.listeners = new Set(); + this.addListener = cb => this.listeners.add(cb); + this.removeListener = cb => this.listeners.delete(cb); + this.dispatch = msg => this.listeners.forEach(l => l(msg)); +} - listeners[port.name](port); +function Port(magic) +{ + this.name = magic; + this.onDisconnect = new EvTarget(); + this.onMessage = new EvTarget(); + this.postMessage = msg => this.other.onMessage.dispatch(msg); + this.disconnect = () => this.other.onDisconnect.dispatch(this.other); } -browser.runtime.onConnect.addListener(raw_listen); +let bg_page_url; +function connect_to_background(magic) +{ + if (bg_page_url === undefined) + bg_page_url = browser.runtime.getURL("_generated_background_page.html"); + if (typeof document === "undefined" || document.URL !== bg_page_url) + return browser.runtime.connect({name: magic}); -#EXPORT listen_for_connection + if (!(magic in listeners)) + throw `no listener for '${magic}'` + + const ports = [new Port(magic), new Port(magic)]; + ports[0].other = ports[1]; + ports[1].other = ports[0]; + + listeners[magic](ports[0]); + return ports[1]; +} + +#EXPORT connect_to_background |