mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 1146724 - Use a SendingContext for WebChannels. r=MattN/markh
This commit is contained in:
parent
dc08d9fe3d
commit
4b8dab2a11
@ -277,7 +277,7 @@ addEventListener("WebChannelMessageToChrome", function (e) {
|
||||
let principal = e.target.nodePrincipal ? e.target.nodePrincipal : e.target.document.nodePrincipal;
|
||||
|
||||
if (e.detail) {
|
||||
sendAsyncMessage("WebChannelMessageToChrome", e.detail, null, principal);
|
||||
sendAsyncMessage("WebChannelMessageToChrome", e.detail, { eventTarget: e.target }, principal);
|
||||
} else {
|
||||
Cu.reportError("WebChannel message failed. No message detail.");
|
||||
}
|
||||
@ -286,12 +286,30 @@ addEventListener("WebChannelMessageToChrome", function (e) {
|
||||
// Add message listener for "WebChannelMessageToContent" messages from chrome scripts
|
||||
addMessageListener("WebChannelMessageToContent", function (e) {
|
||||
if (e.data) {
|
||||
content.dispatchEvent(new content.CustomEvent("WebChannelMessageToContent", {
|
||||
detail: Cu.cloneInto({
|
||||
id: e.data.id,
|
||||
message: e.data.message,
|
||||
}, content),
|
||||
}));
|
||||
// e.objects.eventTarget will be defined if sending a response to
|
||||
// a WebChannelMessageToChrome event. An unsolicited send
|
||||
// may not have an eventTarget defined, in this case send to the
|
||||
// main content window.
|
||||
let eventTarget = e.objects.eventTarget || content;
|
||||
|
||||
// if eventTarget is window then we want the document principal,
|
||||
// otherwise use target itself.
|
||||
let targetPrincipal = eventTarget instanceof Ci.nsIDOMWindow ? eventTarget.document.nodePrincipal : eventTarget.nodePrincipal;
|
||||
|
||||
if (e.principal.subsumes(targetPrincipal)) {
|
||||
// if eventTarget is a window, use it as the targetWindow, otherwise
|
||||
// find the window that owns the eventTarget.
|
||||
let targetWindow = eventTarget instanceof Ci.nsIDOMWindow ? eventTarget : eventTarget.ownerDocument.defaultView;
|
||||
|
||||
eventTarget.dispatchEvent(new targetWindow.CustomEvent("WebChannelMessageToContent", {
|
||||
detail: Cu.cloneInto({
|
||||
id: e.data.id,
|
||||
message: e.data.message,
|
||||
}, targetWindow),
|
||||
}));
|
||||
} else {
|
||||
Cu.reportError("WebChannel message failed. Principal mismatch.");
|
||||
}
|
||||
} else {
|
||||
Cu.reportError("WebChannel message failed. No message data.");
|
||||
}
|
||||
|
@ -163,14 +163,15 @@ this.FxAccountsOAuthClient.prototype = {
|
||||
* Command webChannelId
|
||||
* @param message {Object}
|
||||
* Command message
|
||||
* @param target {EventTarget}
|
||||
* Channel message event target
|
||||
* @param sendingContext {Object}
|
||||
* Channel message event sendingContext
|
||||
* @private
|
||||
*/
|
||||
let listener = function (webChannelId, message, target) {
|
||||
let listener = function (webChannelId, message, sendingContext) {
|
||||
if (message) {
|
||||
let command = message.command;
|
||||
let data = message.data;
|
||||
let target = sendingContext && sendingContext.browser;
|
||||
|
||||
switch (command) {
|
||||
case "oauth_complete":
|
||||
|
@ -66,11 +66,15 @@ let WebChannelBroker = Object.create({
|
||||
*/
|
||||
_listener: function (event) {
|
||||
let data = event.data;
|
||||
let sender = event.target;
|
||||
let sendingContext = {
|
||||
browser: event.target,
|
||||
eventTarget: event.objects.eventTarget,
|
||||
principal: event.principal,
|
||||
};
|
||||
|
||||
if (data && data.id) {
|
||||
if (!event.principal) {
|
||||
this._sendErrorEventToContent(data.id, sender, "Message principal missing");
|
||||
this._sendErrorEventToContent(data.id, sendingContext, "Message principal missing");
|
||||
} else {
|
||||
let validChannelFound = false;
|
||||
data.message = data.message || {};
|
||||
@ -79,13 +83,13 @@ let WebChannelBroker = Object.create({
|
||||
if (channel.id === data.id &&
|
||||
channel._originCheckCallback(event.principal)) {
|
||||
validChannelFound = true;
|
||||
channel.deliver(data, sender);
|
||||
channel.deliver(data, sendingContext);
|
||||
}
|
||||
}
|
||||
|
||||
// if no valid origins send an event that there is no such valid channel
|
||||
if (!validChannelFound) {
|
||||
this._sendErrorEventToContent(data.id, sender, "No Such Channel");
|
||||
this._sendErrorEventToContent(data.id, sendingContext, "No Such Channel");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -108,20 +112,24 @@ let WebChannelBroker = Object.create({
|
||||
*
|
||||
* @param id {String}
|
||||
* The WebChannel id to include in the message
|
||||
* @param sender {EventTarget}
|
||||
* EventTarget with a "messageManager" that will send be used to send the message
|
||||
* @param sendingContext {Object}
|
||||
* Message sending context
|
||||
* @param [errorMsg] {String}
|
||||
* Error message
|
||||
* @private
|
||||
*/
|
||||
_sendErrorEventToContent: function (id, sender, errorMsg) {
|
||||
_sendErrorEventToContent: function (id, sendingContext, errorMsg) {
|
||||
let { browser: targetBrowser, eventTarget, principal: targetPrincipal } = sendingContext;
|
||||
|
||||
errorMsg = errorMsg || "Web Channel Broker error";
|
||||
|
||||
if (sender.messageManager) {
|
||||
sender.messageManager.sendAsyncMessage("WebChannelMessageToContent", {
|
||||
if (targetBrowser && targetBrowser.messageManager) {
|
||||
targetBrowser.messageManager.sendAsyncMessage("WebChannelMessageToContent", {
|
||||
id: id,
|
||||
error: errorMsg,
|
||||
}, sender);
|
||||
}, { eventTarget: eventTarget }, targetPrincipal);
|
||||
} else {
|
||||
Cu.reportError("Failed to send a WebChannel error. Target invalid.");
|
||||
}
|
||||
Cu.reportError(id.toString() + " error message. " + errorMsg);
|
||||
},
|
||||
@ -211,8 +219,17 @@ this.WebChannel.prototype = {
|
||||
* The WebChannel id that was used for this message
|
||||
* @param {Object} message
|
||||
* The message itself
|
||||
* @param {EventTarget} sender
|
||||
* The source of the message
|
||||
* @param sendingContext {Object}
|
||||
* The sending context of the source of the message. Can be passed to
|
||||
* `send` to respond to a message.
|
||||
* @param sendingContext.browser {browser}
|
||||
* The <browser> object that captured the
|
||||
* WebChannelMessageToChrome.
|
||||
* @param sendingContext.eventTarget {EventTarget}
|
||||
* The <EventTarget> where the message was sent.
|
||||
* @param sendingContext.principal {Principal}
|
||||
* The <Principal> of the EventTarget where the
|
||||
* message was sent.
|
||||
*/
|
||||
listen: function (callback) {
|
||||
if (this._deliverCallback) {
|
||||
@ -239,16 +256,27 @@ this.WebChannel.prototype = {
|
||||
*
|
||||
* @param message {Object}
|
||||
* The message object that will be sent
|
||||
* @param target {browser}
|
||||
* The <browser> object that has a "messageManager" that sends messages
|
||||
*
|
||||
* @param target {Object}
|
||||
* A <target> with the information of where to send the message.
|
||||
* @param target.browser {browser}
|
||||
* The <browser> object with a "messageManager" that will
|
||||
* be used to send the message.
|
||||
* @param target.principal {Principal}
|
||||
* Principal of the target. Prevents messages from
|
||||
* being dispatched to unexpected origins. The system principal
|
||||
* can be specified to send to any target.
|
||||
* @param [target.eventTarget] {EventTarget}
|
||||
* Optional eventTarget within the browser, use to send to a
|
||||
* specific element, e.g., an iframe.
|
||||
*/
|
||||
send: function (message, target) {
|
||||
if (message && target && target.messageManager) {
|
||||
target.messageManager.sendAsyncMessage("WebChannelMessageToContent", {
|
||||
let { browser, principal, eventTarget } = target;
|
||||
|
||||
if (message && browser && browser.messageManager && principal) {
|
||||
browser.messageManager.sendAsyncMessage("WebChannelMessageToContent", {
|
||||
id: this.id,
|
||||
message: message
|
||||
});
|
||||
}, { eventTarget }, principal);
|
||||
} else if (!message) {
|
||||
Cu.reportError("Failed to send a WebChannel message. Message not set.");
|
||||
} else {
|
||||
@ -261,18 +289,26 @@ this.WebChannel.prototype = {
|
||||
*
|
||||
* @param data {Object}
|
||||
* Message data
|
||||
* @param sender {browser}
|
||||
* Message sender
|
||||
* @param sendingContext {Object}
|
||||
* Message sending context.
|
||||
* @param sendingContext.browser {browser}
|
||||
* The <browser> object that captured the
|
||||
* WebChannelMessageToChrome.
|
||||
* @param sendingContext.eventTarget {EventTarget}
|
||||
* The <EventTarget> where the message was sent.
|
||||
* @param sendingContext.principal {Principal}
|
||||
* The <Principal> of the EventTarget where the message was sent.
|
||||
*
|
||||
*/
|
||||
deliver: function(data, sender) {
|
||||
deliver: function(data, sendingContext) {
|
||||
if (this._deliverCallback) {
|
||||
try {
|
||||
this._deliverCallback(data.id, data.message, sender);
|
||||
this._deliverCallback(data.id, data.message, sendingContext);
|
||||
} catch (ex) {
|
||||
this.send({
|
||||
errno: ERRNO_UNKNOWN_ERROR,
|
||||
error: ex.message ? ex.message : ERROR_UNKNOWN
|
||||
}, sender);
|
||||
}, sendingContext);
|
||||
Cu.reportError("Failed to execute callback:" + ex);
|
||||
}
|
||||
} else {
|
||||
|
@ -77,7 +77,9 @@ add_task(function test_web_channel_broker_listener() {
|
||||
},
|
||||
principal: {
|
||||
origin: URL_STRING
|
||||
}
|
||||
},
|
||||
objects: {
|
||||
},
|
||||
};
|
||||
|
||||
WebChannelBroker._listener(mockEvent);
|
||||
|
Loading…
Reference in New Issue
Block a user