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

Compatibility with environments that have the `browser` namespace but don't support promises #3

Open
snoack opened this Issue Oct 21, 2016 · 20 comments

Comments

Projects
None yet
@snoack

snoack commented Oct 21, 2016

This polyfill seems to be incompatible with Microsoft Edge, which doesn't support promises yet, but is using the browser instead of the chrome namespace.

@snoack snoack changed the title from Compatibility with environments that have the `browser` namespace but don't support promises to Compatibility with environments that have the `browser` namespace but don't support promises (i.e. Microsoft Edge) Oct 21, 2016

@snoack snoack changed the title from Compatibility with environments that have the `browser` namespace but don't support promises (i.e. Microsoft Edge) to Compatibility with environments that have the `browser` namespace but don't support promises Oct 21, 2016

@kmaglione

This comment has been minimized.

Show comment
Hide comment
@kmaglione

kmaglione Nov 6, 2016

Collaborator

Edge is planning to add promise support, but yes, I've been thinking about ways to detect this and add support where it's not available.

Collaborator

kmaglione commented Nov 6, 2016

Edge is planning to add promise support, but yes, I've been thinking about ways to detect this and add support where it's not available.

@snoack

This comment has been minimized.

Show comment
Hide comment
@snoack

snoack Nov 9, 2016

Well, I presume it will still take a while until Microsoft Edge will support promises, and when it does extension developers might not be able to drop support for older versions of Microsoft Edge right away. Also what if Chrome (or a new platform) will start to provide the browser namespace but doesn't support promises in the same step.

As for detecting the promise-based API, the best idea I have is just calling any asynchronous function and check whether it throws an exception (because a callback is expected) or whether a promise is returned.

if (typeof browser == "undefined")
  var browser = chrome;

var _supportsPromises = false;
try {
  _supportsPromises = browser.runtime.getPlatformInfo() instanceof Promise;
}
catch (e)
{
}

if (!_supportsPromises)
  browser = wrapAPI(browser);

snoack commented Nov 9, 2016

Well, I presume it will still take a while until Microsoft Edge will support promises, and when it does extension developers might not be able to drop support for older versions of Microsoft Edge right away. Also what if Chrome (or a new platform) will start to provide the browser namespace but doesn't support promises in the same step.

As for detecting the promise-based API, the best idea I have is just calling any asynchronous function and check whether it throws an exception (because a callback is expected) or whether a promise is returned.

if (typeof browser == "undefined")
  var browser = chrome;

var _supportsPromises = false;
try {
  _supportsPromises = browser.runtime.getPlatformInfo() instanceof Promise;
}
catch (e)
{
}

if (!_supportsPromises)
  browser = wrapAPI(browser);
@DaAwesomeP

This comment has been minimized.

Show comment
Hide comment
@DaAwesomeP

DaAwesomeP Apr 16, 2017

Here's the issue on the Microsoft end: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9421085/. Maybe they'll post an update if a decent amount of people click the "Me too" button.

DaAwesomeP commented Apr 16, 2017

Here's the issue on the Microsoft end: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9421085/. Maybe they'll post an update if a decent amount of people click the "Me too" button.

@myfreeweb

This comment has been minimized.

Show comment
Hide comment
@myfreeweb

myfreeweb Apr 22, 2017

Changed Status from “Confirmed” to “By design”

:(

myfreeweb commented Apr 22, 2017

Changed Status from “Confirmed” to “By design”

:(

@DaAwesomeP

This comment has been minimized.

Show comment
Hide comment
@DaAwesomeP

DaAwesomeP Apr 26, 2017

James M. Apr 24, 2017 Microsoft Edge Team

Hello,

Thank you for providing this information about the issue. A Microsoft Edge Extension does not support the Promise model; this is a documented difference between Mozilla and Edge’s platform. Currently, we do not plan to release a fix. Please update this case if you can provide new information for us to consider.

Best Wishes,
The MS Edge Team

https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9421085/

DaAwesomeP commented Apr 26, 2017

James M. Apr 24, 2017 Microsoft Edge Team

Hello,

Thank you for providing this information about the issue. A Microsoft Edge Extension does not support the Promise model; this is a documented difference between Mozilla and Edge’s platform. Currently, we do not plan to release a fix. Please update this case if you can provide new information for us to consider.

Best Wishes,
The MS Edge Team

https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9421085/

@myfreeweb

This comment has been minimized.

Show comment
Hide comment
@myfreeweb

myfreeweb Apr 30, 2017

Considering Microsoft's track record of not following standards and their somewhat recent desire to not be like that anymore, it's really weird that they're so dismissive about this…

I guess supporting this in the polyfill would be the only solution for now :(

myfreeweb commented Apr 30, 2017

Considering Microsoft's track record of not following standards and their somewhat recent desire to not be like that anymore, it's really weird that they're so dismissive about this…

I guess supporting this in the polyfill would be the only solution for now :(

@Noitidart

This comment has been minimized.

Show comment
Hide comment
@Noitidart

Noitidart Apr 30, 2017

Ideally I would like to use this polyfill but due to edge I was using this really short polyfill and it was working well:

@constfun I find this works for me across all browsers including edge:

const deepAccessUsingString = (obj, dotpath) => dotpath.split('.').reduce((nested, key) => nested[key], obj);

window.extension = typeof chrome !== 'undefined' && chrome.runtime ? chrome : browser;
window.extensiona = function(dotpath, ...args) {
    let basepath = dotpath.split('.');
    basepath.pop();
    basepath = basepath.join('.');
    return new Promise(resolve => deepAccessUsingString(TRUNK, dotpath)(...args, resolve));
}

Usage example:

/* USAGE - sync apis */
extension.browserAction.onClicked.addListener(handleClick);
extension.tabs.create({ url:'blah' }); // if dont care about return
extension.browserAction.setTitle({ title:'rawr' })

/* USAGE - async/callback based api's are as promise */
async function() {
    const info = await extensiona('runtime.getPlatformInfo');
    const tabInfo = await extensiona('tabs.create', { url:'blah' });
    const download = await extensiona('downloads.download', { filename:`filename.here`, url:`www.bing.com/blah` });
    const winId = await extensiona('windows.update', windowid, { focused:true });
}

The only issue i see is in extensiona (the promise version), using deepAccessUsingString might disconnect the api call from the the this. I haven't had issues with it yet though.

To use this, just do extension.** instead of browser.* or chrome.*. If you want callback version.

Edge is also funky in that they have window.chrome, so that's a not good enough test, that's why I test window.chrome.runtime above to see if chrome trunk exists.

Noitidart commented Apr 30, 2017

Ideally I would like to use this polyfill but due to edge I was using this really short polyfill and it was working well:

@constfun I find this works for me across all browsers including edge:

const deepAccessUsingString = (obj, dotpath) => dotpath.split('.').reduce((nested, key) => nested[key], obj);

window.extension = typeof chrome !== 'undefined' && chrome.runtime ? chrome : browser;
window.extensiona = function(dotpath, ...args) {
    let basepath = dotpath.split('.');
    basepath.pop();
    basepath = basepath.join('.');
    return new Promise(resolve => deepAccessUsingString(TRUNK, dotpath)(...args, resolve));
}

Usage example:

/* USAGE - sync apis */
extension.browserAction.onClicked.addListener(handleClick);
extension.tabs.create({ url:'blah' }); // if dont care about return
extension.browserAction.setTitle({ title:'rawr' })

/* USAGE - async/callback based api's are as promise */
async function() {
    const info = await extensiona('runtime.getPlatformInfo');
    const tabInfo = await extensiona('tabs.create', { url:'blah' });
    const download = await extensiona('downloads.download', { filename:`filename.here`, url:`www.bing.com/blah` });
    const winId = await extensiona('windows.update', windowid, { focused:true });
}

The only issue i see is in extensiona (the promise version), using deepAccessUsingString might disconnect the api call from the the this. I haven't had issues with it yet though.

To use this, just do extension.** instead of browser.* or chrome.*. If you want callback version.

Edge is also funky in that they have window.chrome, so that's a not good enough test, that's why I test window.chrome.runtime above to see if chrome trunk exists.

@bfred-it

This comment has been minimized.

Show comment
Hide comment
@bfred-it

bfred-it Aug 20, 2017

Contributor

What a sad state of affairs. It looks like Chrome doesn't care about Mozilla's WebExtensions standardization effort and Edge just (barely) follows whatever Chrome does. On top of that, Chrome's original API is pretty ridiculous to begin with.

At this point I wish mozilla came up with a sound API and polyfilled that.

Contributor

bfred-it commented Aug 20, 2017

What a sad state of affairs. It looks like Chrome doesn't care about Mozilla's WebExtensions standardization effort and Edge just (barely) follows whatever Chrome does. On top of that, Chrome's original API is pretty ridiculous to begin with.

At this point I wish mozilla came up with a sound API and polyfilled that.

@myfreeweb

This comment has been minimized.

Show comment
Hide comment
@myfreeweb

myfreeweb Aug 20, 2017

@bfred-it uhh this repo is exactly the polyfill :)

myfreeweb commented Aug 20, 2017

@bfred-it uhh this repo is exactly the polyfill :)

@bfred-it

This comment has been minimized.

Show comment
Hide comment
@bfred-it

bfred-it Aug 20, 2017

Contributor

Yeah but mozilla's API still looks like browser.runtime.onBrowserUpdateAvailable.addListener(fn)

It could have looked more like a familiar browser.runtime.on('BrowserUpdateAvailable', fn)

Contributor

bfred-it commented Aug 20, 2017

Yeah but mozilla's API still looks like browser.runtime.onBrowserUpdateAvailable.addListener(fn)

It could have looked more like a familiar browser.runtime.on('BrowserUpdateAvailable', fn)

@myfreeweb

This comment has been minimized.

Show comment
Hide comment
@myfreeweb

myfreeweb Aug 20, 2017

that's pretty minor compared to using promises instead of callbacks

myfreeweb commented Aug 20, 2017

that's pretty minor compared to using promises instead of callbacks

@osdiab

This comment has been minimized.

Show comment
Hide comment
@osdiab

osdiab Aug 22, 2017

Aw man, just began working on a Web Extension and ran into this. Hope this can be prioritized soon / maybe I'll try to take a jab at it at some point.

osdiab commented Aug 22, 2017

Aw man, just began working on a Web Extension and ran into this. Hope this can be prioritized soon / maybe I'll try to take a jab at it at some point.

@myfreeweb

This comment has been minimized.

Show comment
Hide comment
@myfreeweb

myfreeweb Aug 22, 2017

@osdiab look at #43 which was mentioned here

myfreeweb commented Aug 22, 2017

@osdiab look at #43 which was mentioned here

@constfun

This comment has been minimized.

Show comment
Hide comment
@constfun

constfun Oct 10, 2017

At the moment, neither a working polyfill, nor any other cross browser solution exists.
An unfortunate state of affairs, but we people of the web are used to this by now.

May I suggest some possible improvements:

  1. Address idiosyncrasies of each browser vendor explicitly, based on the user agent, instead of the current approach.
  2. Instead of polyfilling globals, export an object with Mozilla's version of the API.

On point 1, I argue that it is more robust and simpler than attempting non-trivial feature detection, as in #43. The set of browsers currently supporting WebExtensions is known and the chances of your extension working in some other incarnation of the API without being explicitly targeted is slim.

On point 2, an anecdote.

I just had a fun time on a project that also uses pastak/chrome-browser-object-polyfill. That polyfill makes its own assumptions about the browser global. MetaMask/extensionizer makes different assumptions still.

A cross platform library is more useful to me as a developer than a polyfill that seals off all escape hatches by monkey patching globals.

constfun commented Oct 10, 2017

At the moment, neither a working polyfill, nor any other cross browser solution exists.
An unfortunate state of affairs, but we people of the web are used to this by now.

May I suggest some possible improvements:

  1. Address idiosyncrasies of each browser vendor explicitly, based on the user agent, instead of the current approach.
  2. Instead of polyfilling globals, export an object with Mozilla's version of the API.

On point 1, I argue that it is more robust and simpler than attempting non-trivial feature detection, as in #43. The set of browsers currently supporting WebExtensions is known and the chances of your extension working in some other incarnation of the API without being explicitly targeted is slim.

On point 2, an anecdote.

I just had a fun time on a project that also uses pastak/chrome-browser-object-polyfill. That polyfill makes its own assumptions about the browser global. MetaMask/extensionizer makes different assumptions still.

A cross platform library is more useful to me as a developer than a polyfill that seals off all escape hatches by monkey patching globals.

@franklinyu

This comment has been minimized.

Show comment
Hide comment
@franklinyu

franklinyu Jan 8, 2018

The Edge issue has been re-opened by Edge team…

franklinyu commented Jan 8, 2018

The Edge issue has been re-opened by Edge team…

@Rob--W

This comment has been minimized.

Show comment
Hide comment
@Rob--W

Rob--W May 31, 2018

Member

@rpl and I talked about this:

  • We want to support Edge, with minimal efforts (i.e. no large changes).
  • That is, a simple feature detection as shown in #3 (comment) (guarded on the existence of the Edge-specific msBrowser API).
  • The (existing) browser object will be replaced with the polyfilled one, which uses the global chrome object to implement the polyfill.
  • The polyfill should be tested (at least manually, ideally with continuous integration).
Member

Rob--W commented May 31, 2018

@rpl and I talked about this:

  • We want to support Edge, with minimal efforts (i.e. no large changes).
  • That is, a simple feature detection as shown in #3 (comment) (guarded on the existence of the Edge-specific msBrowser API).
  • The (existing) browser object will be replaced with the polyfilled one, which uses the global chrome object to implement the polyfill.
  • The polyfill should be tested (at least manually, ideally with continuous integration).
@NN---

This comment has been minimized.

Show comment
Hide comment
@NN---

NN--- Jun 17, 2018

@Rob--W Any estimations for including this functionality in webextension-polyfill ?

NN--- commented Jun 17, 2018

@Rob--W Any estimations for including this functionality in webextension-polyfill ?

@ExE-Boss

This comment has been minimized.

Show comment
Hide comment
@ExE-Boss

ExE-Boss Jun 17, 2018

Contributor

@NN--- I’ve been working on a fix in #114.

Contributor

ExE-Boss commented Jun 17, 2018

@NN--- I’ve been working on a fix in #114.

@vozeldr

This comment has been minimized.

Show comment
Hide comment
@vozeldr

vozeldr Aug 20, 2018

Any ideas when this will be completed? I've seen multiple proposed pull requests and they always get shot down for some reason or another. It seems like a lot of "paralysis by over-analysis". It's been almost 2 years. Please implement something, even if it's temporary and not your ideal solution.

vozeldr commented Aug 20, 2018

Any ideas when this will be completed? I've seen multiple proposed pull requests and they always get shot down for some reason or another. It seems like a lot of "paralysis by over-analysis". It's been almost 2 years. Please implement something, even if it's temporary and not your ideal solution.

@Rob--W

This comment has been minimized.

Show comment
Hide comment
@Rob--W

Rob--W Aug 20, 2018

Member

One of the big blockers is the ability to load an extension in Edge for automated testing (locally and on continuous integration, e.g. on AppVeyor).

If someone spends time on researching that, then I am willing to make the desired changes to the polyfill to support Edge.

Member

Rob--W commented Aug 20, 2018

One of the big blockers is the ability to load an extension in Edge for automated testing (locally and on continuous integration, e.g. on AppVeyor).

If someone spends time on researching that, then I am willing to make the desired changes to the polyfill to support Edge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment