Messaging fixes

Checking the message name (and connectorId) is mandatory for Safari,
because when the background page sends a response back to a document,
then all the frames in its owner tab will receive the exact same
message, which could confuse the script in some cases.
This commit is contained in:
Deathamns 2014-11-04 16:31:57 +01:00
parent d98a8161f9
commit e36c7022cf
2 changed files with 33 additions and 24 deletions

View File

@ -177,8 +177,8 @@ if (self.chrome) {
vAPI.messaging = { vAPI.messaging = {
ports: {}, ports: {},
listeners: {}, listeners: {},
listen: function(name, callback) { listen: function(listenerName, callback) {
this.listeners[name] = callback; this.listeners[listenerName] = callback;
}, },
setup: function(connector) { setup: function(connector) {
if (this.connector) { if (this.connector) {
@ -654,8 +654,8 @@ if (self.chrome) {
vAPI.messaging = { vAPI.messaging = {
listeners: {}, listeners: {},
listen: function(name, callback) { listen: function(listenerName, callback) {
this.listeners[name] = callback; this.listeners[listenerName] = callback;
}, },
setup: function(connector) { setup: function(connector) {
if (this.connector) { if (this.connector) {
@ -666,7 +666,7 @@ if (self.chrome) {
var callback = function(response) { var callback = function(response) {
if (request.message.requestId && response !== undefined) { if (request.message.requestId && response !== undefined) {
request.target.page.dispatchMessage( request.target.page.dispatchMessage(
'message', request.name,
{ {
requestId: request.message.requestId, requestId: request.message.requestId,
portName: request.message.portName, portName: request.message.portName,

View File

@ -48,37 +48,40 @@ var messagingConnector = function(response) {
} }
}; };
var uniqueId = function() {
return parseInt(Math.random() * 1e10, 10).toString(36);
};
if (self.chrome) { if (self.chrome) {
vAPI.chrome = true; vAPI.chrome = true;
vAPI.messaging = { vAPI.messaging = {
port: null, port: null,
requestId: 0, requestId: 0,
listenerId: null, connectorId: uniqueId(),
listeners: {}, listeners: {},
channels: {}, channels: {},
connector: messagingConnector, connector: messagingConnector,
setup: function() { setup: function() {
this.listenerId = 'uBlock:' + name + ':' + parseInt(Math.random() * 1e10, 10).toString(36); this.port = chrome.runtime.connect({name: this.connectorId});
this.port = chrome.runtime.connect({name: this.listenerId});
this.port.onMessage.addListener(this.connector); this.port.onMessage.addListener(this.connector);
}, },
close: function() { close: function() {
if (this.port) { if (this.port) {
this.port.disconnect(); this.port.disconnect();
this.port.onMessage.removeListener(this.connector); this.port.onMessage.removeListener(this.connector);
this.channels = this.listeners = this.port = this.listenerId = null; this.port = this.channels = this.listeners = this.connectorId = null;
} }
}, },
channel: function(name, callback) { channel: function(channelName, callback) {
if (!name) { if (!channelName) {
return; return;
} }
this.channels[name] = { this.channels[channelName] = {
portName: name, portName: channelName,
listener: typeof callback === 'function' ? callback : null, listener: typeof callback === 'function' ? callback : null,
send: function(message, callback) { send: function(message, callback) {
if (!vAPI.messaging.listenerId) { if (!vAPI.messaging.port) {
vAPI.messaging.setup(); vAPI.messaging.setup();
} }
@ -99,7 +102,7 @@ if (self.chrome) {
} }
}; };
return this.channels[name]; return this.channels[channelName];
} }
}; };
} else if (self.safari) { } else if (self.safari) {
@ -108,13 +111,19 @@ if (self.chrome) {
// relevant? // relevant?
// https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/MessagesandProxies/MessagesandProxies.html#//apple_ref/doc/uid/TP40009977-CH14-SW12 // https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/MessagesandProxies/MessagesandProxies.html#//apple_ref/doc/uid/TP40009977-CH14-SW12
vAPI.messaging = { vAPI.messaging = {
connectorId: uniqueId(),
requestId: 0, requestId: 0,
listeners: {}, listeners: {},
channels: {}, channels: {},
connector: messagingConnector, connector: messagingConnector,
setup: function() { setup: function() {
this._connector = function(msg) { this._connector = function(msg) {
vAPI.messaging.connector(msg.message); // messages from the background script are sent to every frame,
// so we need to check the connectorId to accept only
// what is meant for the current context
if (msg.name === vAPI.messaging.connectorId) {
vAPI.messaging.connector(msg.message);
}
}; };
safari.self.addEventListener('message', this._connector, false); safari.self.addEventListener('message', this._connector, false);
@ -132,13 +141,13 @@ if (self.chrome) {
this.channels = this.listeners = null; this.channels = this.listeners = null;
} }
}, },
channel: function(name, callback) { channel: function(channelName, callback) {
if (!name) { if (!channelName) {
return; return;
} }
this.channels[name] = { this.channels[channelName] = {
portName: name, portName: channelName,
listener: typeof callback === 'function' ? callback : null, listener: typeof callback === 'function' ? callback : null,
send: function(message, callback) { send: function(message, callback) {
if (!vAPI.messaging._connector) { if (!vAPI.messaging._connector) {
@ -159,7 +168,7 @@ if (self.chrome) {
// popover content doesn't know messaging... // popover content doesn't know messaging...
safari.extension.globalPage.contentWindow safari.extension.globalPage.contentWindow
.vAPI.messaging.connector({ .vAPI.messaging.connector({
name: 'message', name: vAPI.messaging.connectorId,
message: message, message: message,
target: { target: {
page: { page: {
@ -171,7 +180,7 @@ if (self.chrome) {
}); });
} }
else { else {
safari.self.tab.dispatchMessage('message', message); safari.self.tab.dispatchMessage(vAPI.messaging.connectorId, message);
} }
}, },
close: function() { close: function() {
@ -179,7 +188,7 @@ if (self.chrome) {
} }
}; };
return this.channels[name]; return this.channels[channelName];
} }
}; };
@ -258,7 +267,7 @@ if (self.chrome) {
if (!response) { if (!response) {
if (details.type === 'main_frame') { if (details.type === 'main_frame') {
window.stop(); window.stop();
throw Error; throw new Error;
} }
else { else {
e.preventDefault(); e.preventDefault();