diff options
author | gorhill <rhill@raymondhill.net> | 2015-06-29 10:46:20 -0400 |
---|---|---|
committer | gorhill <rhill@raymondhill.net> | 2015-06-29 10:46:20 -0400 |
commit | aeba71790f1385e04b26b79271688d657d9de28e (patch) | |
tree | f07763129dbb0ea312f7ac960fec89b9f976d8b4 /platform/firefox/vapi-client.js | |
parent | 957dea5289f9b6883cbd5aa5403a3fe8438a03a4 (diff) | |
download | uBlock-aeba71790f1385e04b26b79271688d657d9de28e.zip uBlock-aeba71790f1385e04b26b79271688d657d9de28e.tar.gz uBlock-aeba71790f1385e04b26b79271688d657d9de28e.tar.bz2 |
some refactoring: move to-aux-process-messaging timeout into vAPI
Diffstat (limited to 'platform/firefox/vapi-client.js')
-rw-r--r-- | platform/firefox/vapi-client.js | 235 |
1 files changed, 115 insertions, 120 deletions
diff --git a/platform/firefox/vapi-client.js b/platform/firefox/vapi-client.js index 778a7c3..62fa77e 100644 --- a/platform/firefox/vapi-client.js +++ b/platform/firefox/vapi-client.js @@ -67,49 +67,82 @@ vAPI.shutdown = (function() { /******************************************************************************/ -var MessagingListeners = function(callback) { - this.listeners = []; - if ( typeof callback === 'function' ) { - this.listeners.push(callback); - } -}; +vAPI.messaging = { + channels: {}, + pending: {}, + auxProcessId: 1, + connected: false, + connector: function(msg) { + messagingConnector(JSON.parse(msg)); + }, -MessagingListeners.prototype.add = function(callback) { - if ( typeof callback !== 'function' ) { - return; - } - if ( this.listeners.indexOf(callback) !== -1 ) { - throw new Error('Duplicate listener.'); - } - this.listeners.push(callback); -}; + setup: function() { + addMessageListener(this.connector); + this.connected = true; + this.channels['vAPI'] = new MessagingChannel('vAPI', function(msg) { + if ( msg.cmd === 'injectScript' ) { + var details = msg.details; + if ( !details.allFrames && window !== window.top ) { + return; + } + // TODO: investigate why this happens, and if this happens + // legitimately (content scripts not injected I suspect, so + // that would make this legitimate). + // Case: open popup UI from icon in uBlock's logger + if ( typeof self.injectScript === 'function' ) { + self.injectScript(details.file); + } + } + }); + }, -MessagingListeners.prototype.remove = function(callback) { - if ( typeof callback !== 'function' ) { - return; - } - if ( this.listeners.indexOf(callback) === -1 ) { - throw new Error('Listener not found.'); - } - this.listeners.splice(this.listeners.indexOf(callback), 1); -}; + close: function() { + if ( !this.connected ) { + return; + } + removeMessageListener(); + this.connected = false; + this.channels = {}; + this.pending = {}; + }, -MessagingListeners.prototype.removeAll = function() { - this.listeners = []; -}; + channel: function(channelName, callback) { + if ( !channelName ) { + return; + } + var channel = this.channels[channelName]; + if ( channel instanceof MessagingChannel ) { + channel.addListener(callback); + channel.refCount += 1; + } else { + channel = this.channels[channelName] = new MessagingChannel(channelName, callback); + } + return channel; + }, -MessagingListeners.prototype.process = function(msg) { - var listeners = this.listeners; - var n = listeners.length; - for ( var i = 0; i < n; i++ ) { - listeners[i](msg); + toggleListener: function({type, persisted}) { + if ( !vAPI.messaging.connected ) { + return; + } + + if ( type === 'pagehide' ) { + removeMessageListener(); + return; + } + + if ( persisted ) { + addMessageListener(vAPI.messaging.connector); + } } }; +window.addEventListener('pagehide', vAPI.messaging.toggleListener, true); +window.addEventListener('pageshow', vAPI.messaging.toggleListener, true); + /******************************************************************************/ -var messagingConnector = function(response) { - if ( !response ) { +var messagingConnector = function(details) { + if ( !details ) { return; } @@ -118,31 +151,40 @@ var messagingConnector = function(response) { var channel; // Sent to all channels - if ( response.broadcast === true && !response.channelName ) { + if ( details.broadcast === true && !details.channelName ) { for ( channel in channels ) { if ( channels[channel] instanceof MessagingChannel === false ) { continue; } - channels[channel].listeners.process(response.msg); + channels[channel].sendToListeners(details.msg); } return; } // Response to specific message previously sent - if ( response.requestId ) { - var listener = messaging.pending[response.requestId]; - delete messaging.pending[response.requestId]; - delete response.requestId; // TODO: why? + if ( details.auxProcessId ) { + var listener = messaging.pending[details.auxProcessId]; + delete messaging.pending[details.auxProcessId]; + delete details.auxProcessId; // TODO: why? if ( listener ) { - listener(response.msg); + listener(details.msg); return; } } // Sent to a specific channel - channel = channels[response.channelName]; + var response; + channel = channels[details.channelName]; if ( channel instanceof MessagingChannel ) { - channel.listeners.process(response.msg); + response = channel.sendToListeners(details.msg); + } + + // Respond back if required + if ( details.mainProcessId !== undefined ) { + sendAsyncMessage('ublock0:background', { + mainProcessId: details.mainProcessId, + msg: response + }); } }; @@ -150,7 +192,7 @@ var messagingConnector = function(response) { var MessagingChannel = function(name, callback) { this.channelName = name; - this.listeners = new MessagingListeners(callback); + this.listeners = typeof callback === 'function' ? [callback] : []; this.refCount = 1; if ( typeof callback === 'function' ) { var messaging = vAPI.messaging; @@ -161,18 +203,24 @@ var MessagingChannel = function(name, callback) { }; MessagingChannel.prototype.send = function(message, callback) { + this.sendTo(message, undefined, undefined, callback); +}; + +MessagingChannel.prototype.sendTo = function(message, toTabId, toChannel, callback) { var messaging = vAPI.messaging; if ( !messaging.connected ) { messaging.setup(); } - var requestId; + var auxProcessId; if ( callback ) { - requestId = messaging.requestId++; - messaging.pending[requestId] = callback; + auxProcessId = messaging.auxProcessId++; + messaging.pending[auxProcessId] = callback; } sendAsyncMessage('ublock0:background', { channelName: self._sandboxId_ + '|' + this.channelName, - requestId: requestId, + auxProcessId: auxProcessId, + toTabId: toTabId, + toChannel: toChannel, msg: message }); }; @@ -189,7 +237,10 @@ MessagingChannel.prototype.addListener = function(callback) { if ( typeof callback !== 'function' ) { return; } - this.listeners.add(callback); + if ( this.listeners.indexOf(callback) !== -1 ) { + throw new Error('Duplicate listener.'); + } + this.listeners.push(callback); var messaging = vAPI.messaging; if ( !messaging.connected ) { messaging.setup(); @@ -200,86 +251,30 @@ MessagingChannel.prototype.removeListener = function(callback) { if ( typeof callback !== 'function' ) { return; } - this.listeners.remove(callback); + var pos = this.listeners.indexOf(callback); + if ( pos === -1 ) { + throw new Error('Listener not found.'); + } + this.listeners.splice(pos, 1); }; MessagingChannel.prototype.removeAllListeners = function() { - this.listeners.removeAll(); + this.listeners = []; }; -/******************************************************************************/ - -vAPI.messaging = { - channels: {}, - pending: {}, - requestId: 1, - connected: false, - connector: function(msg) { - messagingConnector(JSON.parse(msg)); - }, - - setup: function() { - addMessageListener(this.connector); - this.connected = true; - this.channels['vAPI'] = new MessagingChannel('vAPI', function(msg) { - if ( msg.cmd === 'injectScript' ) { - var details = msg.details; - if ( !details.allFrames && window !== window.top ) { - return; - } - // TODO: investigate why this happens, and if this happens - // legitimately (content scripts not injected I suspect, so - // that would make this legitimate). - // Case: open popup UI from icon in uBlock's logger - if ( typeof self.injectScript === 'function' ) { - self.injectScript(details.file); - } - } - }); - }, - - close: function() { - if ( !this.connected ) { - return; - } - removeMessageListener(); - this.connected = false; - this.channels = {}; - this.pending = {}; - }, - - channel: function(channelName, callback) { - if ( !channelName ) { - return; - } - var channel = this.channels[channelName]; - if ( channel instanceof MessagingChannel ) { - channel.addListener(callback); - channel.refCount += 1; - } else { - channel = this.channels[channelName] = new MessagingChannel(channelName, callback); - } - return channel; - }, - - toggleListener: function({type, persisted}) { - if ( !vAPI.messaging.connected ) { - return; - } - - if ( type === 'pagehide' ) { - removeMessageListener(); - return; - } - - if ( persisted ) { - addMessageListener(vAPI.messaging.connector); +MessagingChannel.prototype.sendToListeners = function(msg) { + var response; + var listeners = this.listeners; + for ( var i = 0, n = listeners.length; i < n; i++ ) { + response = listeners[i](msg); + if ( response !== undefined ) { + break; } } + return response; }; -window.addEventListener('pagehide', vAPI.messaging.toggleListener, true); -window.addEventListener('pageshow', vAPI.messaging.toggleListener, true); +// https://www.youtube.com/watch?v=Cg0cmhjdiLs /******************************************************************************/ |