Skip to content
This repository has been archived by the owner on Jul 3, 2018. It is now read-only.

Commit

Permalink
Merge m-c to autoland, a=merge CLOSED TREE
Browse files Browse the repository at this point in the history
  • Loading branch information
KWierso committed Jul 21, 2016
2 parents 1bc7c6b + 4969042 commit f57633e
Showing 1 changed file with 57 additions and 46 deletions.
103 changes: 57 additions & 46 deletions toolkit/mozapps/extensions/amWebAPI.js
Expand Up @@ -41,13 +41,9 @@ const APIBroker = {
return;
}

let { resolve, reject } = this._promises.get(payload.callbackID);
let resolve = this._promises.get(payload.callbackID);
this._promises.delete(payload.callbackID);

if ("resolve" in payload)
resolve(payload.resolve);
else
reject(payload.reject);
resolve(payload);
break;
}

Expand All @@ -71,10 +67,10 @@ const APIBroker = {
},

sendRequest: function(type, ...args) {
return new Promise((resolve, reject) => {
return new Promise(resolve => {
let callbackID = this._nextID++;

this._promises.set(callbackID, { resolve, reject });
this._promises.set(callbackID, resolve);
Services.cpmm.sendAsyncMessage(MSG_PROMISE_REQUEST, { type, callbackID, args });
});
},
Expand Down Expand Up @@ -120,41 +116,59 @@ function AddonInstall(window, properties) {
}

/**
* API methods should return promises from the page, this is a simple wrapper
* to make sure of that. It also automatically wraps objects when necessary.
* API methods all return promises from content. They also follow a
* similar pattern of sending a request to the parent process, then
* wrapping the returned object or error appropriately for the page.
* We must take care only to wrap and reject with errors that are meant
* to be visible to content, and not internal errors.
* This function is a wrapper to handle the common bits.
*
* apiRequest is the name of the command to invoke in the parent process
* apiArgs is a callable that takes the content-provided args for the
* method and returns the arguments to send in the request to
* the parent process.
* if processor is non-null, it is called on the returned object to
* convert the result from the parent process back to an
* object appropriate for content.
*
* Both apiArgs and processor are called with "this" bound to the value
* that is held when the actual api method was called.
*/
function WebAPITask(generator) {
function WebAPITask(apiRequest, apiArgs, processor) {
return function(...args) {
let task = Task.async(generator.bind(this));

let win = this.window;

let wrapForContent = (obj) => {
if (obj instanceof Addon) {
return win.Addon._create(win, obj);
}
if (obj instanceof AddonInstall) {
return win.AddonInstall._create(win, obj);
}

return obj;
}
let boundApiArgs = apiArgs.bind(this);
let boundProcessor = processor ? processor.bind(this) : null;

return new win.Promise((resolve, reject) => {
task(...args).then(wrapForContent)
.then(resolve, reject);
Task.spawn(function* () {
let sendArgs = boundApiArgs(...args);
let result = yield APIBroker.sendRequest(apiRequest, ...sendArgs);
if ("reject" in result) {
let err = new win.Error(result.reject.message);
// We don't currently put any other properties onto Errors
// generated by mozAddonManager. If/when we do, they will
// need to get copied here.
reject(err);
return;
}

let obj = result.resolve;
if (boundProcessor) {
obj = boundProcessor(obj);
}
resolve(obj);
}).catch(err => {
Cu.reportError(err);
reject(new win.Error("Unexpected internal error"));
});
});
}
}

Addon.prototype = {
uninstall: WebAPITask(function*() {
return yield APIBroker.sendRequest("addonUninstall", this.id);
}),

setEnabled: WebAPITask(function* (value) {
return yield APIBroker.sendRequest("addonSetEnabled", this.id, value);
}),
uninstall: WebAPITask("addonUninstall", function() { return [this.id]; }),
setEnabled: WebAPITask("addonSetEnabled", function(value) {return [this.id, value]; }),
};

const INSTALL_EVENTS = [
Expand All @@ -181,13 +195,8 @@ AddonInstall.prototype = {
this.__DOM_IMPL__.dispatchEvent(event);
},

install: WebAPITask(function*() {
yield APIBroker.sendRequest("addonInstallDoInstall", this.id);
}),

cancel: WebAPITask(function*() {
yield APIBroker.sendRequest("addonInstallCancel", this.id);
}),
install: WebAPITask("addonInstallDoInstall", function() { return [this.id]; }),
cancel: WebAPITask("addonInstallCancel", function() { return [this.id]; }),
};

function WebAPI() {
Expand All @@ -204,19 +213,21 @@ WebAPI.prototype = {
});
},

getAddonByID: WebAPITask(function*(id) {
let addonInfo = yield APIBroker.sendRequest("getAddonByID", id);
return addonInfo ? new Addon(this.window, addonInfo) : null;
getAddonByID: WebAPITask("getAddonByID", id => [id], function(addonInfo) {
if (!addonInfo) {
return null;
}
let addon = new Addon(this.window, addonInfo);
return this.window.Addon._create(this.window, addon);
}),

createInstall: WebAPITask(function*(options) {
let installInfo = yield APIBroker.sendRequest("createInstall", options);
createInstall: WebAPITask("createInstall", options => [options], function(installInfo) {
if (!installInfo) {
return null;
}
let install = new AddonInstall(this.window, installInfo);
this.allInstalls.push(installInfo.id);
return install;
return this.window.AddonInstall._create(this.window, install);
}),

eventListenerWasAdded(type) {
Expand Down

0 comments on commit f57633e

Please sign in to comment.