diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/broadcast.js | 6 | ||||
-rw-r--r-- | common/indexeddb.js | 4 | ||||
-rw-r--r-- | common/message_server.js | 61 |
3 files changed, 60 insertions, 11 deletions
diff --git a/common/broadcast.js b/common/broadcast.js index b69f352..b7743a6 100644 --- a/common/broadcast.js +++ b/common/broadcast.js @@ -43,12 +43,12 @@ #IMPORT common/connection_types.js AS CONNECTION_TYPE -#FROM common/browser.js IMPORT browser +#FROM common/message_server.js IMPORT connect_to_background function sender_connection() { return { - port: browser.runtime.connect({name: CONNECTION_TYPE.BROADCAST_SEND}) + port: connect_to_background(CONNECTION_TYPE.BROADCAST_SEND) }; } #EXPORT sender_connection @@ -94,7 +94,7 @@ function flush(sender_conn) function listener_connection(cb) { const conn = { - port: browser.runtime.connect({name: CONNECTION_TYPE.BROADCAST_LISTEN}) + port: connect_to_background(CONNECTION_TYPE.BROADCAST_LISTEN) }; conn.port.onMessage.addListener(cb); diff --git a/common/indexeddb.js b/common/indexeddb.js index c97c115..096391a 100644 --- a/common/indexeddb.js +++ b/common/indexeddb.js @@ -45,7 +45,11 @@ #IMPORT common/broadcast.js let initial_data = ( +#IF UNIT_TEST + {} +#ELSE #INCLUDE_VERBATIM default_settings.json +#ENDIF ); /* Update when changes are made to database schema. Must have 3 elements */ 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 |