0

Since Opera supports the Chrome extension API, it is almost possible to run a full-featured Chrome extension on this browser. However there are still some missing features in the API.

Is there a simple and efficient way to check if an extension is currently running on Opera or Google Chrome?


The specific use case I'm facing is when invoking chrome.notifications.create: on Google Chrome it is possible to set a buttons attribute to add buttons to it. Opera does not support it and instead of ignoring the attribute, it throws an error:

Unchecked runtime.lastError while running notifications.create: Adding buttons to notifications is not supported.

So I need a way to check the browser beforehand instead of handling the error.

guillaumekln
  • 504
  • 5
  • 17
  • The moral of the answer is that if you want to figure out if a feature is available, then you should use feature detection, not determining the browser and version. Otherwise, Opera will implement the feature, but your extension won't work. – Teepeemm Sep 26 '15 at 17:55

2 Answers2

3

You're asking the wrong question in the title. If the notification button works in Chrome but not in Opera, then don't try to detect Opera, but detect that buttons are not working and provide a fallback. For instance:

var options = {
    type: 'basic',
    iconUrl: '/icon.png',
    title: 'My notification',
    message: 'My message',
    buttons: [{
        title: 'Button text',
    }],
};
chrome.notifications.create(options, function onCreatedCallback() {
    var lastError = chrome.runtime.lastError;
    if (lastError && lastError.message === 'Adding buttons to notifications is not supported.') {
        delete options.buttons;
        chrome.notifications.create(options, onCreatedCallback);
    } else if (lastError) {
        console.warn('Failed to create notification: ' + lastError.message);
    } else {
        console.log('Created notification');
    }
});

If you run into a case where you do want to detect an Opera extension environment and use an Opera-specific extension API, you could use typeof opr == 'object' (which is the namespace for Opera-only extension APIs).

Otherwise, you could use UA-sniffing to distinguish Opera from Chrome: /OPR/.test(navigator.userAgent).

If you just want to detect a specific version of Chrome/Opera (e.g. because of a browser bug that cannot be detected in any way), use user agent sniffing (How to find the version of Chrome browser from my extension?).

Rob W
  • 341,306
  • 83
  • 791
  • 678
  • Thanks for the answer but the reason I don't want to just use the fallback on error is because I propose to my users an option to enable/disable this particular button. On Opera I would like to simply hide this option as I know buttons are not supported. In addition, `typeof opr == 'object'` returns `false` in Opera 32.0. – guillaumekln Sep 26 '15 at 13:48
  • @guillaumekln `opr` only becomes available when the Opera-specific API is enabled in the manifest file. Another options that always works (without extensions) is checking whether the UA string contains "OPR" (see updated answer). But even for your specific use case, you could just use `chrome.notifications.create` followed by `chrome.notifications.clear` to see whether the feature is supported or not. – Rob W Sep 26 '15 at 13:57
0

From How to determine in which browser your extension background script is executing?

var isOpera = (!!window.opr && !!opr.addons) || !!window.opera ||
    navigator.userAgent.indexOf(' OPR/') >= 0;
4b0
  • 21,981
  • 30
  • 95
  • 142
john k
  • 6,268
  • 4
  • 55
  • 59