Bug 1400256 - Serialise IPC messages with evaluate.toJSON. r?whimboo
Instead of having commands serialising their own JSON-safe messages
when communicating with the content frame script, this patch changes
the AsyncMessageChannel to use evaluate.toJSON.
MozReview-Commit-ID: LmAVGEjqMTB
--- a/testing/marionette/proxy.js
+++ b/testing/marionette/proxy.js
@@ -8,16 +8,17 @@ const {classes: Cc, interfaces: Ci, util
Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const {
error,
WebDriverError,
} = Cu.import("chrome://marionette/content/error.js", {});
+Cu.import("chrome://marionette/content/evaluate.js");
Cu.import("chrome://marionette/content/modal.js");
this.EXPORTED_SYMBOLS = ["proxy"];
const uuidgen = Cc["@mozilla.org/uuid-generator;1"]
.getService(Ci.nsIUUIDGenerator);
const logger = Log.repository.getLogger("Marionette");
@@ -121,53 +122,54 @@ proxy.AsyncMessageChannel = class {
let uuid = uuidgen.generateUUID().toString();
// TODO(ato): Bug 1242595
this.activeMessageId = uuid;
return new Promise((resolve, reject) => {
let path = proxy.AsyncMessageChannel.makePath(uuid);
let cb = msg => {
this.activeMessageId = null;
+ let {data, type} = msg.json;
switch (msg.json.type) {
case proxy.AsyncMessageChannel.ReplyType.Ok:
case proxy.AsyncMessageChannel.ReplyType.Value:
- resolve(msg.json.data);
+ let payload = evaluate.fromJSON(data);
+ resolve(payload);
break;
case proxy.AsyncMessageChannel.ReplyType.Error:
- let err = WebDriverError.fromJSON(msg.json.data);
+ let err = WebDriverError.fromJSON(data);
reject(err);
break;
default:
- throw new TypeError(
- `Unknown async response type: ${msg.json.type}`);
+ throw new TypeError(`Unknown async response type: ${type}`);
}
};
// The currently selected tab or window has been closed. No clean-up
// is necessary to do because all loaded listeners are gone.
- this.closeHandler = event => {
- logger.debug(`Received DOM event ${event.type} for ${event.target}`);
+ this.closeHandler = ({type, target}) => {
+ logger.debug(`Received DOM event ${type} for ${target}`);
- switch (event.type) {
+ switch (type) {
case "TabClose":
case "unload":
this.removeHandlers();
resolve();
break;
}
};
// A modal or tab modal dialog has been opened. To be able to handle it,
// the active command has to be aborted. Therefore remove all handlers,
// and cancel any ongoing requests in the listener.
this.dialogueObserver_ = (subject, topic) => {
- logger.debug(`Received observer notification "${topic}"`);
+ logger.debug(`Received observer notification ${topic}`);
this.removeAllListeners_();
// TODO(ato): It's not ideal to have listener specific behaviour here:
this.sendAsync("cancelRequest");
this.removeHandlers();
resolve();
};
@@ -254,27 +256,21 @@ proxy.AsyncMessageChannel = class {
} else if (error.isError(obj)) {
let err = error.wrap(obj);
this.sendReply_(uuid, proxy.AsyncMessageChannel.ReplyType.Error, err);
} else {
this.sendReply_(uuid, proxy.AsyncMessageChannel.ReplyType.Value, obj);
}
}
- sendReply_(uuid, type, data = undefined) {
+ sendReply_(uuid, type, payload = undefined) {
const path = proxy.AsyncMessageChannel.makePath(uuid);
- let payload;
- if (data && typeof data.toJSON == "function") {
- payload = data.toJSON();
- } else {
- payload = data;
- }
-
- const msg = {type, data: payload};
+ let data = evaluate.toJSON(payload);
+ const msg = {type, data};
// here sendAsync is actually the content frame's
// sendAsyncMessage(path, message) global
this.sendAsync(path, msg);
}
/**
* Produces a path, or a name, for the message listener handler that