New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for browsers which don’t support Promises #114
Changes from 5 commits
dc836be
320371f
a21cee5
b3609f7
73d5e4b
7a4265b
0cbd8b4
a62cf86
27c9c10
a3f8084
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -6,7 +6,58 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"use strict"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (typeof browser === "undefined") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Returns true if the given object is defined and has an entry with | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* the name `key` and the value of object[key] isn’t undefined. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* @param {*} object The object to test. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* @param {*} key The entry to test for. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* @returns {boolean} True if the value for obj[key] is defined. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const isDefined = (object, key) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (object === window && window !== this) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
object = this; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (typeof object !== "object" || object === null) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return key in object && typeof object[key] !== "undefined"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Returns true if the given object is an object with a `then` method, and can | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* therefore be assumed to behave as a Promise. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* @param {*} value The value to test. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* @returns {boolean} True if the value is thenable. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const isThenable = value => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return value && typeof value === "object" && typeof value.then === "function"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (typeof browser === "undefined" || !(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// If `browser.runtime.lastError` doesn’t exist, assume promies are supported. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let supportsPromises = !(isDefined(window.browser, "runtime") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
? isDefined(window.browser.runtime, "lastError") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
: isDefined(window.browser, "extension") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
&& isDefined(window.browser.extension, "lastError")); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (supportsPromises) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!supportsPromises) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
supportsPromises |= isThenable(window.browser.runtime.getPlatformInfo()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Microsoft Edge doesn’t support `browser.runtime.getPlatformInfo()` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
supportsPromises |= isThenable(window.browser.windows.get(browser.windows.WINDOW_ID_CURRENT)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (e2) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Do nothing. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return supportsPromises; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
})()) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a bit wordy, how about this function instead? function supportsPromises() {
if (typeof browser === "undefined") {
return false;
}
// If `browser.runtime.lastError` doesn’t exist, assume promises are supported.
if (browser.runtime && typeof browser.runtime.lastError !== "undefined") {
return true;
}
if (browser.extension && typeof browser.extension.lastError !== "undefined") {
return true;
}
try {
return isThenable(browser.runtime.getPlatformInfo());
} catch (error) {}
try {
return isThenable(browser.windows.get(browser.windows.WINDOW_ID_CURRENT));
} catch (error) {}
return false;
}
if (supportsPromises()) { There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Also, the check needs to check for the case when There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just change There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That’s not what your code does. The ternary operator checks for one There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, yours discards the one in
webextension-polyfill/test/test-browser-global.js Lines 29 to 59 in 73d5e4b
Edit: Turns out I forgot to change the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See #114 (comment):
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const SEND_RESPONSE_DEPRECATION_WARNING = ` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Returning a Promise is the preferred way to send a reply from an | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onMessage/onMessageExternal listener, as the sendResponse will be | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -19,7 +70,7 @@ if (typeof browser === "undefined") { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// contents of a function until the first time it's called, and since it will | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// never actually need to be called, this allows the polyfill to be included | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// in Firefox nearly for free. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const wrapAPIs = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const wrapAPIs = chrome => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// NOTE: apiMetadata is associated to the content of the api-metadata.json file | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// at build time by replacing the following "include" with the content of the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// JSON file. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -54,17 +105,6 @@ if (typeof browser === "undefined") { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Returns true if the given object is an object with a `then` method, and can | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* therefore be assumed to behave as a Promise. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* @param {*} value The value to test. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* @returns {boolean} True if the value is thenable. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const isThenable = value => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return value && typeof value === "object" && typeof value.then === "function"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Creates and returns a function which, when called, will resolve or reject | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* the given promise based on how it is called: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -488,7 +528,7 @@ if (typeof browser === "undefined") { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// The build process adds a UMD wrapper around this file, which makes the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// `module` variable available. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
module.exports = wrapAPIs(); // eslint-disable-line no-undef | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
module.exports = wrapAPIs(typeof browser !== "undefined" ? browser : chrome); // eslint-disable-line no-undef | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
module.exports = browser; // eslint-disable-line no-undef | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There’s not need to nest this. If there are no errors, the function will return before the second try/catch