| Index: polyfill.js |
| =================================================================== |
| --- a/polyfill.js |
| +++ b/polyfill.js |
| @@ -38,16 +38,42 @@ |
| "tabs.sendMessage", |
| "tabs.update", |
| "webNavigation.getAllFrames", |
| "webRequest.handlerBehaviorChanged", |
| "windows.create", |
| "windows.update" |
| ]; |
| + // Errors that occur only when we show an interest in the response from an |
| + // API call. |
| + const noFulfillmentErrors = [ |
| + "The message port closed before a response was received." |
| + ]; |
| + |
| + const fulfillmentInterestFlag = Symbol(); |
|
Manish Jethani
2017/10/19 01:59:46
We use a symbol here so it becomes like a private
|
| + |
| + function SpecialPromise(...args) |
| + { |
| + return Reflect.construct(Promise, args, SpecialPromise); |
|
Manish Jethani
2017/10/19 01:59:46
Essentially an extended promise.
|
| + } |
| + |
| + SpecialPromise.prototype = Object.create( |
| + Object.assign({}, Promise.prototype, { |
| + then(...args) |
| + { |
| + // Set this flag to indicate that there is interest in the fulfillment |
| + // of this promise. |
| + this[fulfillmentInterestFlag] = true; |
| + |
| + return Promise.prototype.then.apply(this, args); |
| + } |
| + }) |
| + ); |
| + |
| function wrapAPI(api) |
| { |
| let object = browser; |
| let path = api.split("."); |
| let name = path.pop(); |
| for (let node of path) |
| { |
| @@ -66,27 +92,42 @@ |
| // If the last argument is undefined, we drop it from the list assuming |
| // it stands for the optional callback. We must do this, because we have |
| // to replace it with our own callback. If we simply append our own |
| // callback to the list, it won't match the signature of the function and |
| // will cause an exception. |
| if (typeof args[args.length - 1] == "undefined") |
| args.pop(); |
| - return new Promise((resolve, reject) => |
| + let promise = new SpecialPromise((resolve, reject) => |
| { |
| func.call(object, ...args, result => |
| { |
| let error = browser.runtime.lastError; |
| if (error) |
| + { |
| + // If is this an error we got only because we passed in a callback |
| + // and there's no actual interest in the response, ignore the |
| + // error. |
| + if (noFulfillmentErrors.includes(error.message) && |
| + !promise[fulfillmentInterestFlag]) |
| + { |
| + return; |
| + } |
| + |
| reject(error); |
| + } |
| else |
| + { |
| resolve(result); |
| + } |
| }); |
| }); |
| + |
| + return promise; |
| }; |
| } |
| function shouldWrapAPIs() |
| { |
| try |
| { |
| return !(browser.storage.local.get([]) instanceof Promise); |