aboutsummaryrefslogtreecommitdiffstats
path: root/platform/firefox/vapi-client.js
diff options
context:
space:
mode:
authorgorhill <rhill@raymondhill.net>2015-06-29 10:46:20 -0400
committergorhill <rhill@raymondhill.net>2015-06-29 10:46:20 -0400
commitaeba71790f1385e04b26b79271688d657d9de28e (patch)
treef07763129dbb0ea312f7ac960fec89b9f976d8b4 /platform/firefox/vapi-client.js
parent957dea5289f9b6883cbd5aa5403a3fe8438a03a4 (diff)
downloaduBlock-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.js235
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
/******************************************************************************/