How to implement message passing callbacks in an all-in-one (Edge/Firefox/Chrome) browser extension’s content script?

Development Environment OS: Windows 7 Enterprise LTS
Browser compatibility minimum requirements: Should support all Edge, Firefox, Chrome browsers, as of 2018.
Current ongoing issue: Unable to run VM on dev workstation; Cannot run Windows 10 VMs to debug Microsoft Edge extensions.

To explain:

  • An “all-in-one browser extension” refers to a browser extension code that uses the same code with minor differences to work on various WebExtensions / Chrome Extensions supported browsers. At bare minimum, the same codebase should work and run on Edge, Firefox, and Chrome with very minor changes.
  • Callbacks on the content scripts for Edge/Firefox/Chrome extensions are handled differently.
  • For unknown reasons, I cannot run VM on my workstation machine. When VM is running, VM client is black. This is a localized issue on my end that I cannot resolve, so I’m forced to find a different solution/alternative.

How are they handled differently on the content scripts:

  • Edge: browser.runtime.sendMessage uses callbacks, and returns undefined.
  • Firefox: browser.runtime.sendMessage uses Promises, and returns a Promise.
  • Chrome: chrome.runtime.sendMessage uses callbacks, and returns undefined.

According to various references:

Firefox / Chrome / MS Edge extensions using chrome.* or browser.*

On the content scripts, you can declare the following JavaScript snippet at the top in order to create a global variable that can be referenced everywhere else:

//Global "browser" namespace definition.
window.browser = (function() {
    return window.msBrowser || window.browser ||;

Unfortunately, because of the issue I’m experiencing (VM not running), I cannot tell if window.msBrowser is still being used. And this solution is not helpful for me when handling message callbacks when using namespace.runtime.sendMessage.

With all that said, my main question is: How to write a message passing function that can handle callbacks properly?

Currently, I’m using the following code:

function sendGlobalMessage(messageRequest, callback) {
    if (chrome && window.openDatabase) {
        //This is Chrome browser
        chrome.runtime.sendMessage(messageRequest, callback);
    else if (browser) {
        try {
            //Edge will error out because of a quirk in Edge IndexedDB implementation.
            let db ="edge", (Math.pow(2, 30) + 1));
            db.onerror = function(e) {
                throw new Error("edge is found");
            db.onsuccess = function(e) {
                //This is Firefox browser.
        catch (e) {
            //This is Edge browser
            browser.runtime.sendMessage(messageRequest, callback);

I truly felt this is a hacky solution, because the code is based off of browser platform exclusive quirks in order to separate chrome.runtime.sendMessage and browser.runtime.sendMessage API calls, so as to handle callbacks in their respective platforms. I really wanted to change this.

So I’m asking what better ways are there, out there, that is useful to detect the different platforms, and handle message passing callbacks properly at the same time?

Thanks in advance.

google chrome extension: get cookies in background.js and sendResponse to content.js

My extension adds notify to third-party websites. From this notify I should check if user is logged on our website. I want to check userId from cookies in background.js and send message to content.js. Where I need to know if cookies not empty ( chrome.cookies.get doesn’t available from content.js).

Simple response from works perfectly. And chrome.cookies.get works fine separetaly. But when I try to add condition with get.cookies there is a problem. I guess it because scoupe/context or callbacks trouble.


    function (request, sender, sendResponse) {
        if (request.greeting == "hello") {
            var ID;

            function getCookies(domain, name) {
                chrome.cookies.get({"url": domain, "name": name}, function (cookie) {
                    ID = cookie.value;

            function showId() {
                if (ID) {
                    sendResponse({farewell: "logged"});

            getCookies(baseUrl, COOKIE_KEY_USER_ID);


$(notify).find('[data-act]').on('click', function (e) {

    chrome.runtime.sendMessage({greeting: "hello"}, function(response) {
        if (response && response.farewell == "logged") {
        } else {
            // 'not logged'


Looks like in background.js it doesnt see sendResponse inside another function or Callback. Is there any way to resolve it ? Thanks in advance

variable reassignment inside callback scope [duplicate]

I am trying to assign a preassigned variable to equal to another array inside a callback function.
My description might not be giving you the proper understanding, so here’
s my code:

var extensionListArray = []; {
  extensionListArray = extensionList;
  console.log(extensionList); // logs the expected array contents [{}, {} ...]

console.log(extensionListArray); // logs "[]"

The problem is that it should log the contents of extensionList array but it instead logs []

Edit: The parameter extensionList when console.log(extensionList) does log the array contents, only inside the callback scope though