Menu Search
Jump to the content X X

Sponsored Post Creating One Browser Extension For All Browsers: Edge, Chrome, Firefox, Opera, Brave And Vivaldi

In today’s article, we’ll create a JavaScript extension that works in all major modern browsers, using the very same code base. Indeed, the Chrome extension model based on HTML, CSS and JavaScript is now available almost everywhere, and there is even a Browser Extension Community Group1 working on a standard.

I’ll explain how you can install this extension that supports the web extension model (i.e. Edge, Chrome, Firefox, Opera, Brave and Vivaldi), and provide some simple tips on how to get a unique code base for all of them, but also how to debug in each browser.

Note: We won’t cover Safari in this article because it doesn’t support the same extension model2 as others.

Basics Link

I won’t cover the basics of extension development because plenty of good resources are already available from each vendor:

So, if you’ve never built an extension before or don’t know how it works, have a quick look at those resources. Don’t worry: Building one is simple and straightforward.

Our Extension Link

Let’s build a proof of concept — an extension that uses artificial intelligence (AI) and computer vision to help the blind analyze images on a web page.

We’ll see that, with a few lines of code, we can create some powerful features in the browser. In my case, I’m concerned with accessibility on the web and I’ve already spent some time thinking about how to make a breakout game accessible using web audio and SVG10, for instance.

Still, I’ve been looking for something that would help blind people in a more general way. I was recently inspired while listening to a great talk by Chris Heilmann11 in Lisbon: “Pixels and Hidden Meaning in Pixels12.”

Indeed, using today’s AI algorithms in the cloud, as well as text-to-speech technologies, exposed in the browser with the Web Speech API13 or using a remote cloud service, we can very easily build an extension that analyzes web page images with missing or improperly filled alt text properties.

My little proof of concept simply extracts images from a web page (the one in the active tab) and displays the thumbnails in a list. When you click on one of the images, the extension queries the Computer Vision API to get some descriptive text for the image and then uses either the Web Speech API or Bing Speech API to share it with the visitor.

The video below demonstrates it in Edge, Chrome, Firefox, Opera and Brave.

You’ll notice that, even when the Computer Vision API is analyzing some CGI images, it’s very accurate! I’m really impressed by the progress the industry has made on this in recent months.

I’m using these services:

  • Computer Vision API14, Microsoft Cognitive Services
    This is free to use15 (with a quota). You’ll need to generate a free key; replace the TODO section in the code with your key to make this extension work on your machine. To get an idea of what this API can do, play around with it16.
  • CaptionBot17
  • Bing Text to Speech API18, Microsoft Cognitive Services
    This is also free to use19 (with a quota, too). You’ll need to generate a free key again. We’ll also use a small library20 that I wrote recently to call this API from JavaScript. If you don’t have a Bing key, the extension will always fall back to the Web Speech API, which is supported by all recent browsers.

But feel free to try other similar services:

You can find the code for this small browser extension on my GitHub page23. Feel free to modify the code for other products you want to test.

Tip To Make Your Code Compatible With All Browsers Link

Most of the code and tutorials you’ll find use the namespace chrome.xxx for the Extension API (chrome.tabs, for instance).

But, as I’ve said, the Extension API model is currently being standardized to browser.xxx, and some browsers are defining their own namespaces in the meantime (for example, Edge is using msBrowser).

Fortunately, most of the API remains the same behind the browser. So, it’s very simple to create a little trick to support all browsers and namespace definitions, thanks to the beauty of JavaScript:

window.browser = (function () {
  return window.msBrowser ||
    window.browser ||
    window.chrome;
})();

And voilà!

Of course, you’ll also need to use the subset of the API supported by all browsers. For instance:

Extension Architecture Link

Let’s review together the architecture of this extension. If you’re new to browser extensions, this should help you to understand the flow.

Let’s start with the manifest file27:

Slide128
(View large version29)

This manifest file and its associated JSON is the minimum you’ll need to load an extension in all browsers, if we’re not considering the code of the extension itself, of course. Please check the source30 in my GitHub account, and start from here to be sure that your extension is compatible with all browsers.

For instance, you must specify an author property to load it in Edge; otherwise, it will throw an error. You’ll also need to use the same structure for the icons. The default_title property is also important because it’s used by screen readers in some browsers.

Here are links to the documentation to help you build a manifest file that is compatible everywhere:

The sample extension used in this article is mainly based on the concept of the content script34. This is a script living in the context of the page that we’d like to inspect. Because it has access to the DOM, it will help us to retrieve the images contained in the web page. If you’d like to know more about what a content script is, Opera35, Mozilla36 and Google37 have documentation on it.

Our content script38 is simple:

Slide239
(View large version40)
console.log("Dare Angel content script started");

browser.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    if (request.command == "requestImages") {
        var images = document.getElementsByTagName('img');
        var imagesList = [];
        for (var i = 0; i < images.length; i++) {
            if ((images[i].src.toLowerCase().endsWith(".jpg") || images[i].src.toLowerCase().endsWith(".png"))
                && (images[i].width > 64 && images[i].height > 64)) {
                imagesList.push({ url: images[i].src, alt: images[i].alt });
            }
        }
        sendResponse(JSON.stringify(imagesList));
    }
});
view raw

This first logs into the console to let you check that the extension has properly loaded. Check it via your browser’s developer tool, accessible from F12, Control + Shift + I or ⌘ + ⌥ + I.

It then waits for a message from the UI page with a requestImages command to get all of the images available in the current DOM, and then it returns a list of their URLs if they’re bigger than 64 × 64 pixels (to avoid all of the pixel-tracking junk and low-resolution images).

Slide341
(View large version42)

The popup UI page43 we’re using is very simple and will display the list of images returned by the content script inside a flexbox container44. It loads the start.js script, which immediately creates an instance of dareangel.dashboard.js45 to send a message to the content script to get the URLs of the images in the currently visible tab.

Here’s the code that lives in the UI page, requesting the URLs to the content script:

browser.tabs.query({ active: true, currentWindow: true }, (tabs) => {
    browser.tabs.sendMessage(tabs[0].id, { command: "requestImages" }, (response) => {
        this._imagesList = JSON.parse(response);
        this._imagesList.forEach((element) => {
            var newImageHTMLElement = document.createElement("img");
            newImageHTMLElement.src = element.url;
            newImageHTMLElement.alt = element.alt;
            newImageHTMLElement.tabIndex = this._tabIndex;
            this._tabIndex++;
            newImageHTMLElement.addEventListener("focus", (event) => {
                if (COMPUTERVISIONKEY !== "") {
                    this.analyzeThisImage(event.target.src);
                }
                else {
                    var warningMsg = document.createElement("div");
                    warningMsg.innerHTML = "

Please generate a Computer Vision key in the other tab. Link

"; this._targetDiv.insertBefore(warningMsg, this._targetDiv.firstChild); browser.tabs.create({ active: false, url: "https://www.microsoft.com/cognitive-services/en-US/sign-up?ReturnUrl=/cognitive-services/en-us/subscriptions?productId=%2fproducts%2f54d873dd5eefd00dc474a0f4" }); } }); this._targetDiv.appendChild(newImageHTMLElement); }); }); });

We’re creating image elements. Each image will trigger an event if it has focus, querying the Computer Vision API for review.

This is done by this simple XHR call:

analyzeThisImage(url) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = () => {
        if (xhr.readyState == 4 && xhr.status == 200) {
            var response = document.querySelector('#response');
            var reponse = JSON.parse(xhr.response);
            var resultToSpeak = `With a confidence of ${Math.round(reponse.description.captions[0].confidence * 100)}%, I think it's ${reponse.description.captions[0].text}`;
            console.log(resultToSpeak);
            if (!this._useBingTTS || BINGSPEECHKEY === "") {
                var synUtterance = new SpeechSynthesisUtterance();
                synUtterance.text = resultToSpeak;
                window.speechSynthesis.speak(synUtterance);
            }
            else {
                this._bingTTSclient.synthesize(resultToSpeak);
            }
        }
    };
    xhr.onerror = (evt) => {
        console.log(evt);
    };
    try {
        xhr.open('POST', 'https://api.projectoxford.ai/vision/v1.0/describe');
        xhr.setRequestHeader("Content-Type", "application/json");
        xhr.setRequestHeader("Ocp-Apim-Subscription-Key", COMPUTERVISIONKEY);
        var requestObject = { "url": url };
        xhr.send(JSON.stringify(requestObject));
    }
    catch (ex) {
        console.log(ex);
    }
}
view raw

The following articles will you help you to understand how this Computer Vision API works:

  • Analyzing an Image Version 1.046,” Microsoft Cognitive Services
  • Computer Vision API, v1.047,” Microsoft Cognitive Services
    This shows you via an interactive console in a web page how to call the REST API with the proper JSON properties, and the JSON object you’ll get in return. It’s useful to understand how it works and how you will call it.

In our case, we’re using the describe feature of the API. You’ll also notice in the callback that we will try to use either the Web Speech API or the Bing Text-to-Speech service, based on your options.

Here, then, is the global workflow of this little extension:

Slide448
(View large version49)

Loading The Extension In Each Browser Link

Let’s review quickly how to install the extension in each browser.

Prerequisites Link

Download or clone my small extension50 from GitHub somewhere to your hard drive.

Also, modify dareangel.dashboard.js to add at least a Computer Vision API key. Otherwise, the extension will only be able to display the images extracted from the web page.

Microsoft Edge Link

First, you’ll need at least a Windows 10 Anniversary Update (OS Build 14393+) to have support for extensions in Edge.

Then, open Edge and type about:flags in the address bar. Check the “Enable extension developer features.”

EnableInEdge00151

Click on “…” in the Edge’s navigation bar and then “Extensions” and then “Load extension,” and select the folder where you’ve cloned my GitHub repository. You’ll get this:

52

Click on this freshly loaded extension, and enable “Show button next to the address bar.”

EnableInEdge00353

Note the “Reload extension” button, which is useful while you’re developing your extension. You won’t be forced to remove or reinstall it during the development process; just click the button to refresh the extension.

Navigate to BabylonJS585754, and click on the Dare Angel (DA) button to follow the same demo as shown in the video.

Google Chrome, Opera, Vivaldi Link

In Chrome, navigate to chrome://extensions. In Opera, navigate to opera://extensions. And in Vivaldi, navigate to vivaldi://extensions. Then, enable “Developer mode.”

Click on “Load unpacked extension,” and choose the folder where you’ve extracted my extension.

Chrome00155
(View large version56)

Navigate to BabylonJS585754, and open the extension to check that it works fine.

Mozilla Firefox Link

You’ve got two options here. The first is to temporarily load your extension, which is as easy as it is in Edge and Chrome.

Open Firefox, navigate to about:debugging and click “Load Temporary Add-on.” Then, navigate to the folder of the extension, and select the manifest.json file. That’s it! Now go to BabylonJS585754 to test the extension.

Firefox00159
(View large version60)

The only problem with this solution is that every time you close the browser, you’ll have to reload the extension. The second option would be to use the XPI packaging. You can learn more about this in “Extension Packaging61” on the Mozilla Developer Network.

Brave Link

The public version of Brave doesn’t have a “developer mode” embedded in it to let you load an unsigned extension. You’ll need to build your own version of it by following the steps in “Loading Chrome Extensions in Brave62.”

As explained in that article, once you’ve cloned Brave, you’ll need to open the extensions.js file in a text editor. Locate the lines below, and insert the registration code for your extension. In my case, I’ve just added the two last lines:

  // Manually install the braveExtension and torrentExtension
  extensionInfo.setState(config.braveExtensionId, extensionStates.REGISTERED)
  loadExtension(config.braveExtensionId, getExtensionsPath('brave'), generateBraveManifest(), 'component')

  extensionInfo.setState('DareAngel', extensionStates.REGISTERED)
  loadExtension('DareAngel', getExtensionsPath('DareAngel/'))
view raw

Copy the extension to the app/extensions folder. Open two command prompts in the browser-laptop folder. In the first one, launch npm run watch, and wait for webpack to finish building Brave’s Electron app. It should say, “webpack: bundle is now VALID.” Otherwise, you’ll run into some issues.

Brave00163
(View large version64)

Then, in the second command prompt, launch npm start, which will launch our slightly custom version of Brave.

In Brave, navigate to about:extensions, and you should see the extension displayed and loaded in the address bar.

Brave00265
(View large version66)

Debugging The Extension In Each Browser Link

Tip for all browsers: Using console.log(), simply log some data from the flow of your extension. Most of the time, using the browser’s developer tools, you’ll be able to click on the JavaScript file that has logged it to open it and debug it.

Microsoft Edge Link

To debug the client script part, living in the context of the page, you just need to open F12. Then, click on the “Debugger” tab and find your extension’s folder.

Open the script file that you’d like to debug — dareangel.client.js, in my case — and debug your code as usual, setting up breakpoints, etc.

DebugInEdge00167
(View large version68)

If your extension creates a separate tab to do its job (like the Page Analyzer69, which our Vorlon.js70 team published in the store), simply press F12 on that tab to debug it.

DebugInEdge00271
(View large version72)

If you’d like to debug the popup page, you’ll first need to get the ID of your extension. To do that, simply go into the property of the extension and you’ll find an ID property:

DebugInEdge00373

Then, you’ll need to type in the address bar something like ms-browser-extension://ID_of_your_extension/yourpage.html. In our case, it would be ms-browser-extension://DareAngel_vdbyzyarbfgh8/dashboard.html. Then, simply use F12 on this page:

DebugInEdge00474
(View large version75)

Google Chrome, Opera, Vivaldi, Brave Link

Because Chrome and Opera rely on the same Blink code base, they share the same debugging process. Even though Brave and Vivaldi are forks of Chromium, they also share the same debugging process most of the time.

To debug the client script part, open the browser’s developer tools on the page that you’d like to debug (pressing F12, Control + Shift + I or ⌘ + ⌥ + I, depending on the browser or platform you’re using).

Then, click on the “Content scripts” tab and find your extension’s folder. Open the script file that you’d like to debug, and debug your code just as you would do with any JavaScript code.

DebugInChrome00176
(View large version77)

To debug a tab that your extension would create, it’s exactly the same as with Edge: Simply use the developer tools.

DebugInChrome00278
(View large version79)

For Chrome and Opera, to debug the popup page, right-click on the button of your extension next to the address bar and choose “Inspect popup,” or open the HTML pane of the popup and right-click inside it to “Inspect.” Vivaldi only supports right-click and then “Inspect” inside the HTML pane once opened.

DebugInChrome00380
(View large version81)

For Brave, it’s the same process as with Edge. You first need to find the GUID associated with your extension in about:extensions:

BraveDebug00182

And then, in a separate tab, open the page you’d like to debug like — in my case, chrome-extension://bodaahkboijjjodkbmmddgjldpifcjap/dashboard.html — and open developer tools.

BraveDebug00283
(View large version84)

For the layout, you have a bit of help using Shift + F8, which will let you inspect the complete frame of Brave. And you’ll discover that Brave is an Electron app using React!

Note, for instance, the data-reactroot attribute.

BraveDebug00385
(View large version86)

Note: I had to slightly modify the CSS of the extension for Brave because it currently displays popups with a transparent background by default, and I also had some issues with the height of my images collection. I’ve limited it to four elements in Brave.

Mozilla Firefox Link

Mozilla has really great documentation on debugging web extensions87.

For the client script part, it’s the same as in Edge, Chrome, Opera and Brave. Simply open the developer tools in the tab you’d like to debug, and you’ll find a moz-extension://guid section with your code to debug:

DebugInFirefox00188
(View large version89)

If you need to debug a tab that your extension would create (like Vorlon.js’ Page Analyzer extension), simply use the developer tools:

DebugInFirefox00290
(View large version91)

Finally, debugging a popup is a bit more complex but is well explained in the “Debugging Popups92” section of the documentation.

DebugInFirefox00393
(View large version94)

Publishing Your Extension In Each Store Link

Each vendor has detailed documentation on the process to follow to publish your extension in its store. They all take similar approaches. You need to package the extension in a particular file format — most of the time, a ZIP-like container. Then, you have to submit it in a dedicated portal, choose a pricing model and wait for the review process to complete. If accepted, your extension will be downloadable in the browser itself by any user who visits the extensions store.

Here are the various processes:

Please note that submitting a Microsoft Edge extension to the Windows Store is currently a restricted capability. Reach out to the Microsoft Edge team99 with your request to be a part of the Windows Store, and they’ll consider you for a future update.

I’ve tried to share as much of what I’ve learned from working on our Vorlon.js Page Analyzer extension100 and this little proof of concept.

Some developers remember the pain of working through various implementations to build their extension — whether it meant using different build directories, or working with slightly different extension APIs, or following totally different approaches, such as Firefox’s XUL extensions or Internet Explorer’s BHOs and ActiveX.

It’s awesome to see that, today, using our regular JavaScript, CSS and HTML skills, we can build great extensions using the very same code base and across all browsers!

Feel free to ping me on Twitter101 for any feedback.

(ms, vf, rb, yk, al, il)

Footnotes Link

  1. 1 https://browserext.github.io/
  2. 2 https://developer.apple.com/reference/safariextensions
  3. 3 https://developer.chrome.com/extensions
  4. 4 https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/extensions/
  5. 5 https://channel9.msdn.com/Events/WebPlatformSummit/edgesummit2016/ES1614?wt.mc_id=DX_879946&OC.ID=DX_879946&CR_CC=DX_879946
  6. 6 https://developer.mozilla.org/en-US/Add-ons/WebExtensions
  7. 7 https://wiki.mozilla.org/WebExtensions
  8. 8 https://dev.opera.com/extensions/getting-started/
  9. 9 https://github.com/brave/browser-laptop/wiki/Developer-Notes-on-Installing-or-Updating-Extensions
  10. 10 https://www.davrous.com/2015/08/27/creating-an-accessible-breakout-game-using-web-audio-svg/
  11. 11 https://twitter.com/codepo8
  12. 12 https://www.youtube.com/watch?v=TWVNTsdm27U
  13. 13 https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
  14. 14 https://www.microsoft.com/cognitive-services/en-us/computer-vision-api
  15. 15 https://www.microsoft.com/cognitive-services/en-us/subscriptions?productId=/products/54d873dd5eefd00dc474a0f4
  16. 16 https://www.captionbot.ai/
  17. 17 https://www.smashingmagazine.com/wp-content/uploads/2016/12/CaptionBot-1-preview-opt.png
  18. 18 https://www.microsoft.com/cognitive-services/en-us/speech-api
  19. 19 https://www.microsoft.com/cognitive-services/en-us/subscriptions?productId=/products/Bing.Speech.Preview
  20. 20 https://github.com/davrous/BingTTSClientJSLib
  21. 21 https://visual-recognition-demo.mybluemix.net/
  22. 22 https://cloud.google.com/vision/
  23. 23 http://github.com/davrous/dareangel
  24. 24 https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/extensions/api-support/
  25. 25 https://developer.mozilla.org/en-US/Add-ons/WebExtensions
  26. 26 https://dev.opera.com/extensions/apis/
  27. 27 https://github.com/davrous/dareangel/blob/master/manifest.json
  28. 28 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Slide1-large-opt.png
  29. 29 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Slide1-large-opt.png
  30. 30 https://github.com/davrous/dareangel/blob/master/manifest.json
  31. 31 https://developer.chrome.com/extensions/manifest
  32. 32 https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/extensions/api-support/supported-manifest-keys/
  33. 33 https://developer.mozilla.org/en-US/Add-ons/WebExtensions/manifest.json
  34. 34 https://dev.opera.com/extensions/architecture-overview/#the-content-script
  35. 35 https://dev.opera.com/extensions/content-scripts/
  36. 36 https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Content_scripts
  37. 37 https://developer.chrome.com/extensions/content_scripts
  38. 38 https://github.com/davrous/dareangel/blob/master/dareangel.client.ts
  39. 39 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Slide2-large-opt.png
  40. 40 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Slide2-large-opt.png
  41. 41 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Slide3-large-opt.png
  42. 42 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Slide3-large-opt.png
  43. 43 https://github.com/davrous/dareangel/blob/master/dashboard.html
  44. 44 https://github.com/davrous/dareangel/blob/master/dashboard.css
  45. 45 https://github.com/davrous/dareangel/blob/master/dareangel.dashboard.js
  46. 46 https://www.microsoft.com/cognitive-services/en-us/Computer-Vision-API/documentation/AnalyzeImage
  47. 47 https://dev.projectoxford.ai/docs/services/56f91f2d778daf23d8ec6739/operations/56f91f2e778daf14a499e1fa
  48. 48 https://www.smashingmagazine.com/wp-content/uploads/2016/12/xSlide4_thumb-large-opt.png
  49. 49 https://www.smashingmagazine.com/wp-content/uploads/2016/12/xSlide4_thumb-large-opt.png
  50. 50 https://github.com/davrous/dareangel
  51. 51 https://www.smashingmagazine.com/wp-content/uploads/2016/12/EnableInEdge001-1-preview-opt.png
  52. 52 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Edge001-preview-opt.png
  53. 53 https://www.smashingmagazine.com/wp-content/uploads/2016/12/EnableInEdge003-1-preview-opt.png
  54. 54 http://www.babylonjs.com/
  55. 55 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Chrome001-large-opt.png
  56. 56 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Chrome001-large-opt.png
  57. 57 http://www.babylonjs.com/
  58. 58 http://www.babylonjs.com/
  59. 59 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Firefox001-large-opt.png
  60. 60 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Firefox001-large-opt.png
  61. 61 https://developer.mozilla.org/en-US/Add-ons/Extension_Packaging
  62. 62 https://blog.brave.com/loading-chrome-extensions-in-brave/
  63. 63 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Brave001-large-opt.png
  64. 64 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Brave001-large-opt.png
  65. 65 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Brave002-large-opt.png
  66. 66 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Brave002-large-opt.png
  67. 67 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInEdge001-large-opt.png
  68. 68 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInEdge001-large-opt.png
  69. 69 https://www.microsoft.com/store/p/page-analyzer/9nblggh4qws7
  70. 70 http://www.vorlonjs.io/
  71. 71 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInEdge002-large-opt.png
  72. 72 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInEdge002-large-opt.png
  73. 73 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInEdge003-preview-opt.png
  74. 74 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInEdge004-large-opt.png
  75. 75 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInEdge004-large-opt.png
  76. 76 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInChrome001-large-opt.png
  77. 77 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInChrome001-large-opt.png
  78. 78 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInChrome002-large-opt.png
  79. 79 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInChrome002-large-opt.png
  80. 80 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInChrome003-1-large-opt.jpg
  81. 81 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInChrome003-1-large-opt.jpg
  82. 82 https://www.smashingmagazine.com/wp-content/uploads/2016/12/BraveDebug001-preview-opt.png
  83. 83 https://www.smashingmagazine.com/wp-content/uploads/2016/12/BraveDebug002-large-opt.png
  84. 84 https://www.smashingmagazine.com/wp-content/uploads/2016/12/BraveDebug002-large-opt.png
  85. 85 https://www.smashingmagazine.com/wp-content/uploads/2016/12/BraveDebug003-large-opt.jpg
  86. 86 https://www.smashingmagazine.com/wp-content/uploads/2016/12/BraveDebug003-large-opt.jpg
  87. 87 https://developer.mozilla.org/fr/Add-ons/WebExtensions/Debugging
  88. 88 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInFirefox001-large-opt.png
  89. 89 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInFirefox001-large-opt.png
  90. 90 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInFirefox002-large-opt.png
  91. 91 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInFirefox002-large-opt.png
  92. 92 https://developer.mozilla.org/fr/Add-ons/WebExtensions/Debugging
  93. 93 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInFirefox003-large-opt.jpg
  94. 94 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInFirefox003-large-opt.jpg
  95. 95 https://developer.chrome.com/webstore/publish
  96. 96 https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Publishing_your_WebExtension
  97. 97 https://dev.opera.com/extensions/publishing-guidelines/
  98. 98 https://docs.microsoft.com/en-us/microsoft-edge/extensions/guides/packaging
  99. 99 http://aka.ms/extension-request
  100. 100 https://www.microsoft.com/store/p/page-analyzer/9nblggh4qws7
  101. 101 https://twitter.com/davrous

↑ Back to top Tweet itShare on Facebook

David Rousset is a Senior Program Manager at Microsoft, in charge of driving adoption of HTML5 standards. He has been a speaker at several famous web conferences such as Paris Web, CodeMotion, ReasonsTo or jQuery UK. He’s the co-author of the WebGL Babylon.js open-source engine. Read his blog on MSDN or follow him on Twitter.

  1. 1

    Nice post… I like it very much.

    5
  2. 2

    Herbert Dupree, II

    April 13, 2017 12:57 pm

    I’m mostly an end user primarily of Vivaldi 1.8 but have all the browsers except Safari on my system that I use at various times. Since Vivaldi is a highly skinned Chromium browser, is there significant differences between Google’s implementation and Vivaldi’s? I know there are some differences with Opera. I’m aware that those extensions that require Google account logins do not currently work with Vivaldi, and may never do so.

    My side project is to have a browser extension that provides the information that Firefox does natively in the View Info.

    0

Leave a Comment

You may use simple HTML to add links or lists to your comment. Also, use <pre><code class="language-*">...</code></pre> to mark up code snippets. We support -js, -markup and -css for comments.

↑ Back to top