WebExtension: Detect install or update/upgrade and display HTML page

Hello there!
I would like to display a HTML page with version specific changes etc when my addon has been updated. Is there a built-in mechanism for this or do I need to put version in storage.local, do a check and then display?

If I must use storage, what is the difference between chrome.storage and browser.storage?
They both seem to be supported by FF.

Also, for my HTML page…
Do I simply create the HTML page and include it in web_accessible_resources then display it?
Or does AMO have a place to upload this and then display it automatically upon update/upgrade?
TIA

EDIT: My addon only utilizes content scripts. No background scripts.
Not sure if that is a factor or not…

if you want to know what is the difference between chrome.storage and browser.storage then you can read it http://stackoverflow.com/questions/24279495/window-localstorage-vs-chrome-storage-local,

yeah you can create addons with simple HTML page with web_accessible_resources

1 Like

Thank you for the reply hashemirafsan.
That link does not apply in my case. I’m not referring to HTML5 storage but extension storage.
Chrome API uses chrome.storage.local
FireFox (in the example) specifies browser.storage.local
They both seem to be supported by FireFox. I want to know the difference between their usage cases. Should I use “browser”? Is “browser” compatible with Chrome?

I would rather use code that will work the same in Chrome and FireFox to minimize code differences between my addon for FireFox and my Chrome version.

I think you can use runtime.onInstalled, it has a onInstalledReason - https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onInstalled

However you will have to use a background script. Especially if you want to open new tab to a html page. Which you would do with .tabs.create(...).

I actually don’t like the onInstalled it doesn’t work like I expect so I do it manually with .storage like this:

let cur_version = chrome.runtime.getManifest().version;
let mem_lastversion = await browser.storage.local.get('mem_lastversion');
if (!mem_lastversion) {
    // is install
} else if (mem_lastversion !== cur_version) {
    if (isSemVer(nub.self.version, '>' + lastversion)) {
        // is upgrade
    } else {
        // downgrade
    }
}
// else just a regular startup - addon was already installed

I use the isSemVer a tiny version comparator function you can grab from here - https://gist.github.com/cowboy/566233

2 Likes

Thank you noitidart! Sorry it took so long to reply back, but I wanted to read your code, research, absorb more info and test, test, test… lol

What was your “bad” experience with onInstalled? My first concern was that I see conflicting version compatibility numbers. onInstalled states v52 support and onInstalledReason states v45 support. I am VERY concerned about browser backward compatibility (WebExtension support). I didn’t even test these. It seemed to me a waste of time…

I decided to follow your suggestion and use the storage.local method.
I am now using your isSemVer in my addon (with your copyright intact of course). Thank you very much for sharing! I did make a few changes to the code you posted though. First of all, “nub.self.version” is nonexistent. I’m guessing it is addon specific? I just replaced that with cur_version.

Secondly, using “await” in the promise makes me anxious. I see that support for await starts at v52 and Chrome v55. So, at first I changed that to using “mem_lastversion.then”. Then I found that older version of chrome didn’t like it. So I changed to using a callback function instead.

Which brings me to the difference between chrome.storage.local and browser.storage.local. As I stated, I found that FF v52 supports “chrome” and “browser”. Chrome (in my testing) does not support “browser”. So, I made the change to use chrome.storage.local instead.

Of course, I created a background script and used messaging to open the new tab with my html pages (one for install and one for update).

So… Here is what I ended up with that is backward compatible with Chrome (tested in v44), Opera (tested in v36) and works in latest FF Aurora v52.

Background js:

chrome.runtime.onMessage.addListener(
   function(request, sender, sendResponse) {
      var n="", a=request.update;
      if(a=="update"){n="EnhancedUpdated.html";}
      else if(a=="install"){n="EnhancedInstalled.html";}
//      "Downgrade" is ignored for now.
      if(n){chrome.tabs.create({url:n});}
   });

Code at bottom of content script:

/*!
 * isSemVer - v0.1 - 9/05/2010
 * http://benalman.com/
 * http://semver.org/
 *
 * Copyright (c) 2010 "Cowboy" Ben Alman
 * Dual licensed under the MIT and GPL licenses.
 * http://benalman.com/about/license/
 */
var isSemVer= GET CODE FROM GITHUB IN PREVIOUS POST

var cur_version = chrome.runtime.getManifest().version;
chrome.storage.local.get("lastversion", function(res){
   var n="", last=res.lastversion;
   if (!last) {n="install";}
   else if (last !== cur_version) {
      if (isSemVer(cur_version, '>' + last)) {
         n="update";
      } else {n="downgrade";}
   }
   if(n){
      chrome.runtime.sendMessage({update: n});
      chrome.storage.local.set({lastversion: cur_version});
   }
});

Through testing, this seems to be working perfectly…
I am still concerned about the use of “chrome” instead of “browser”. I am curious as to why FF is using “browser” instead. Will “chrome” support be dropped in favor of “browser”? Am I missing something basic here?

noitidart (or anyone else), do you see anything to be concerned about or have any comments or insight into my code strategy? Thank you once again for helping!

onInstalled is only supported in Firefox from version 52. So if you need it to work before that, you can’t use it.

I’d also like to know why onInstalled didn’t work for you, noitidart: this seems like a perfect use for it. If there are problems with it, is it worth filing a bug?

Firefox, and the draft standard being developed in the W3C (https://browserext.github.io/browserext/, https://www.w3.org/community/browserext/), use “browser” as the namespace name, and promises for asynchronous functions.

Firefox also supports “chrome” and callbacks, as an aid to people porting from Chrome. Mozilla has also written a polyfill which enables code that uses “browser” and promises to work unchanged in Chrome: https://github.com/mozilla/webextension-polyfill.

To make things more complicated, Edge (AFAIK) only supports “browser” and callbacks, although I believe that they intend to add support for promises.

For APIs that are implemented in Google Chrome, I think it’s unlikely that Firefox will drop support for the “chrome” shim.

1 Like

I can’t detect startup due to regular startup (not due to installed/updated/downgraded).

Thank you very much wbamberg!
THAT is the type of detailed info I was seeking. :slight_smile:

Follow up:
My addon auto updated without issue on all devices.
My installed html page opened in a new tab as expected.

Except android FF: It auto updated but it did NOT open a new tab with the installation details as it should have. Does android block the opening of a new tab? Is there something I can change in my code previously posted to enable some type of notification for android users?