diff options
author | Alessio Vanni <vannilla@firemail.cc> | 2019-06-23 02:34:09 +0200 |
---|---|---|
committer | Alessio Vanni <vannilla@firemail.cc> | 2019-06-23 02:34:09 +0200 |
commit | d9858f22244f58eb2a305aa2e42439c77acdb861 (patch) | |
tree | 7fc3de4a91a03806c891acbf11e0cc5f1c524145 /js/vapi-messaging.js | |
parent | e29205dc4d013704cd6b1ee2fd7b7dc0ef226c01 (diff) | |
download | ematrix-d9858f22244f58eb2a305aa2e42439c77acdb861.tar.lz ematrix-d9858f22244f58eb2a305aa2e42439c77acdb861.tar.xz ematrix-d9858f22244f58eb2a305aa2e42439c77acdb861.zip |
Make messaging its own file
Also reorganize the Makefile a bit.
Diffstat (limited to 'js/vapi-messaging.js')
-rw-r--r-- | js/vapi-messaging.js | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/js/vapi-messaging.js b/js/vapi-messaging.js new file mode 100644 index 0000000..abed913 --- /dev/null +++ b/js/vapi-messaging.js @@ -0,0 +1,144 @@ +/******************************************************************************* + + ηMatrix - a browser extension to black/white list requests. + Copyright (C) 2014-2019 The uMatrix/uBlock Origin authors + Copyright (C) 2019 Alessio Vanni + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see {http://www.gnu.org/licenses/}. + + Home: https://gitlab.com/vannilla/ematrix + uMatrix Home: https://github.com/gorhill/uMatrix +*/ + +/* global self, Components */ + +// For background page (tabs management) + +'use strict'; + +/******************************************************************************/ + +(function () { + const {classes: Cc, interfaces: Ci, utils: Cu} = Components; + const {Services} = Cu.import('resource://gre/modules/Services.jsm', null); + + let vAPI = self.vAPI; // Guaranteed to be initialized by vapi-background.js + + vAPI.messaging = { + get globalMessageManager() { + return Cc['@mozilla.org/globalmessagemanager;1'] + .getService(Ci.nsIMessageListenerManager); + }, + frameScript: vAPI.getURL('frameScript.js'), + listeners: {}, + defaultHandler: null, + NOOPFUNC: function(){}, + UNHANDLED: 'vAPI.messaging.notHandled' + }; + + vAPI.messaging.listen = function (listenerName, callback) { + this.listeners[listenerName] = callback; + }; + + vAPI.messaging.onMessage = function ({target, data}) { + let messageManager = target.messageManager; + + if (!messageManager) { + // Message came from a popup, and its message manager is + // not usable. So instead we broadcast to the parent + // window. + messageManager = + vAPI.browser. + getOwnerWindow(target.webNavigation + .QueryInterface(Ci.nsIDocShell) + .chromeEventHandler).messageManager; + } + + let channelNameRaw = data.channelName; + let pos = channelNameRaw.indexOf('|'); + let channelName = channelNameRaw.slice(pos + 1); + + let callback = vAPI.messaging.NOOPFUNC; + if (data.requestId !== undefined) { + callback = CallbackWrapper.factory(messageManager, + channelName, + channelNameRaw.slice(0, pos), + data.requestId).callback; + } + + let sender = { + tab: { + id: vAPI.tabs.manager.tabIdFromTarget(target) + } + }; + + // Specific handler + let r = vAPI.messaging.UNHANDLED; + let listener = vAPI.messaging.listeners[channelName]; + + if (typeof listener === 'function') { + r = listener(data.msg, sender, callback); + } + if (r !== vAPI.messaging.UNHANDLED) { + return; + } + + // Default handler + r = vAPI.messaging.defaultHandler(data.msg, sender, callback); + if (r !== vAPI.messaging.UNHANDLED) { + return; + } + + console.error('eMatrix> messaging > unknown request: %o', data); + + // Unhandled: Need to callback anyways in case caller expected + // an answer, or else there is a memory leak on caller's side + callback(); + }; + + vAPI.messaging.setup = function (defaultHandler) { + // Already setup? + if (this.defaultHandler !== null) { + return; + } + + if (typeof defaultHandler !== 'function') { + defaultHandler = function () { + return vAPI.messaging.UNHANDLED; + }; + } + + this.defaultHandler = defaultHandler; + this.globalMessageManager.addMessageListener(location.host + + ':background', + this.onMessage); + this.globalMessageManager.loadFrameScript(this.frameScript, true); + + vAPI.addCleanUpTask(function () { + let gmm = vAPI.messaging.globalMessageManager; + + gmm.removeDelayedFrameScript(vAPI.messaging.frameScript); + gmm.removeMessageListener(location.host + ':background', + vAPI.messaging.onMessage); + }); + }; + + vAPI.messaging.broadcast = function (message) { + this.globalMessageManager + .broadcastAsyncMessage(location.host + ':broadcast', + JSON.stringify({ + broadcast: true, + msg: message})); + }; +})(); |