Bug 1402944: Part 8 - Avoid X-ray overhead when cloning event handler responses. r?mixedpuppy
MozReview-Commit-ID: 4CHP80WymuA
--- a/toolkit/components/extensions/ExtensionChild.jsm
+++ b/toolkit/components/extensions/ExtensionChild.jsm
@@ -823,19 +823,26 @@ class ChildAPIManager {
switch (name || messageName) {
case "API:RunListener":
let map = this.listeners.get(data.path);
let listener = map.ids.get(data.listenerId);
if (listener) {
let args = data.args.deserialize(this.context.cloneScope);
- let fire = () => this.context.runSafeWithoutClone(listener, ...args);
- return (data.handlingUserInput) ?
- withHandlingUserInput(this.context.contentWindow, fire) : fire();
+ let fire = () => this.context.applySafeWithoutClone(listener, args);
+ return Promise.resolve(
+ data.handlingUserInput ? withHandlingUserInput(this.context.contentWindow, fire)
+ : fire())
+ .then(result => {
+ if (result !== undefined) {
+ return new StructuredCloneHolder(result, this.context.cloneScope);
+ }
+ return result;
+ });
}
if (!map.removedIds.has(data.listenerId)) {
Services.console.logStringMessage(
`Unknown listener at childId=${data.childId} path=${data.path} listenerId=${data.listenerId}\n`);
}
break;
case "API:CallResult":
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -64,16 +64,18 @@ let schemaURLs = new Set();
schemaURLs.add("chrome://extensions/content/schemas/experiments.json");
let GlobalManager;
let ParentAPIManager;
let ProxyMessenger;
let StartupCache;
+const global = this;
+
// This object loads the ext-*.js scripts that define the extension API.
let apiManager = new class extends SchemaAPIManager {
constructor() {
super("main");
this.initialized = null;
this.on("startup", (event, extension) => { // eslint-disable-line mozilla/balanced-listeners
let promises = [];
@@ -778,16 +780,18 @@ ParentAPIManager = {
childId,
handlingUserInput,
listenerId: data.listenerId,
path: data.path,
args: new StructuredCloneHolder(listenerArgs),
},
{
recipient: {childId},
+ }).then(result => {
+ return result && result.deserialize(global);
});
}
context.listenerProxies.set(data.listenerId, listener);
let args = data.args;
let promise = context.apiCan.asyncFindAPIPath(data.path);