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 returnsundefined
. - Firefox:
browser.runtime.sendMessage
uses Promises, and returns a Promise. - Chrome:
chrome.runtime.sendMessage
uses callbacks, and returnsundefined
.
According to various references:
Firefox / Chrome / MS Edge extensions using chrome.* or browser.*
https://www.smashingmagazine.com/2017/04/browser-extension-edge-chrome-firefox-opera-brave-vivaldi/
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 || window.chrome;
})();
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.
//See https://gist.github.com/nolanlawson/a841ee23436410f37168
let db = window.indexedDB.open("edge", (Math.pow(2, 30) + 1));
db.onerror = function(e) {
throw new Error("edge is found");
};
db.onsuccess = function(e) {
//This is Firefox browser.
browser.runtime.sendMessage(messageRequest).then(callback);
};
}
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.