The best practice to detect whether a browser extension is running on Chrome or Firefox? [duplicate]
B

1

6

I have written a Chrome extension and I am migrating it to other browsers like Firefox and Edge. However, the WebExtensions API on Firefox has some differences compared to Chrome's API.

So I have to detect whether I should use callback-style APIs (in Chrome, as well as in Edge) or the promise-style APIs (in Firefox).

For example:

if(RUNNING_ON_CHROME)
    chrome.permissions.request({
        permissions: ...,
        origins: ...,
    }, function(result) { // callback-style
        ...
    });
else // running on firefox
    browser.permissions.request({
        permissions: ...,
        origins: ...,
    }).then(function(result) { // promise-style
        ...
    });

I'm wondering how can I perform the RUNNING_ON_CHROME test. Should I check the related string in UserAgent, or check browser!==undefined?

ps. Edge uses browser.* APIs but its API is callback-styled.

Bargain answered 31/8, 2017 at 15:31 Comment(6)
Best practises can be opinionated depending on the individual.Klinges
Could you do something like browser = browser || chrome?Vally
@Vally No, since they have different signatures. There is a polyfill maintained by Mozilla though.Immedicable
@Vally their API have some differences. Like the code in my problem, Chrome uses callback and Firefox uses Promise. Mozilla does have a polyfill for it but it's too heavyweight for my extension.Bargain
@Bargain Define "too heavyweight". After all, you're not loading the script over network, so size has less impact..Immedicable
Why would you want to have different code to use browser.* and Promises on Firefox while also having code that uses chrome.* and callbacks on Chrome? Just use chrome.* and callbacks on both. Firefox fully supports using callbacks and the chrome.* namespace for direct code compatibility (with some differences), where Firefox implements the API at all.Earpiercing
I
4

As of right now, you can rely on browser and chrome:

(no longer works for detecting Edge since the switch to Chromium-based engine)

function getBrowser() {
  if (typeof chrome !== "undefined") {
    if (typeof browser !== "undefined") {
      return "Firefox";
    } else {
      return "Chrome";
    }
  } else {
    return "Edge";
  }
}

On one hand, using this every time you want to call the API is going to be full of boilerplate; you can polyfill one of them (e.g. using webextension-polyfill to get browser in Chrome) and use only one.

On the other hand, there are real differences in implementation (even if you get the same signatures), so you will need the above browser detection to separate some logic.

Immedicable answered 31/8, 2017 at 15:38 Comment(4)
You might want to mention that Firefox natively supports using the chrome.* namespace and callbacks. Thus, the easiest code-compatibility between Chrome and Firefox is to just use chrome.* in both. You only need to use the browser.* polyfill if really want to use Promises.Earpiercing
@Earpiercing Edge was explicitly mentioned in the question.Immedicable
But, in Edge they use callbacks anyway. Thus, you can generally just alias chrome = browser in Edge. However, I've not extensively tested in Edge, as what testing I did do (early in the year) indicated that extension support was too unstable for reasonable development (i.e. it was a pain in the rear, and I didn't have a compelling business reason).Earpiercing
This answer no longer works as Edge now shares Chrome APIs: blogs.windows.com/windowsexperience/2018/12/06/…Velocity

© 2022 - 2024 — McMap. All rights reserved.