Add support for Manifest V3

Manifest V3 (MV3) is a new version of the manifest.json file, which also
comes with several API changes:
https://developer.chrome.com/docs/extensions/mv3/intro/

Therefore, this change does the following:

- Add a new target to the Makefile and release.bash scripts called
  "chromium-mv3-beta"/"CHROMIUM_MV3" which target Chromium using
  Manifest V3.
- Adapt the manifest.gjson template so it is compatible with Manifest
  V3 when the target is "CHROMIUM_MV3".
- Adapt the source code (change the background page to a service
  worker and change chrome.browserAction.* to chrome.action.*).

Also, the following change has been done:

- The "gecko-beta" target in the Makefile has been removed because in
  the end we never released beta versions for Firefox, due to the small
  user base there.

Change-Id: Ibedcd6651cd23aa3db359a1ef7c7b96a232f39a7
diff --git a/Makefile b/Makefile
index a2fb83e..c630cf7 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
-.PHONY: all chromium-stable chromium-beta gecko-stable gecko-beta clean
+.PHONY: all chromium-stable chromium-beta chromium-mv3-beta gecko-stable clean
 
-all: chromium-stable chromium-beta gecko-stable gecko-beta
+all: chromium-stable chromium-beta chromium-mv3-beta gecko-stable
 
 chromium-stable:
 	bash release.bash -c stable -b chromium
@@ -8,11 +8,11 @@
 chromium-beta:
 	bash release.bash -c beta -b chromium
 
+chromium-mv3-beta:
+	bash release.bash -c beta -b chromium_mv3
+
 gecko-stable:
 	bash release.bash -c stable -b gecko
 
-gecko-beta:
-	bash release.bash -c beta -b gecko
-
 clean:
 	rm -rf out
diff --git a/README.md b/README.md
index f5ab3eb..1ab9140 100644
--- a/README.md
+++ b/README.md
@@ -69,7 +69,8 @@
 
 Run `make all` to build the extension for all the available channels and
 browsers. You can also run `make {target}` where `{target}` is one of the
-following: `chromium-stable`, `chromium-beta`, `gecko-stable`, `gecko-beta`.
+following: `chromium-stable`, `chromium-beta`, `chromium-mv3-beta`,
+`gecko-stable`.
 
 Run `make clean` to clean all the release files (this removes the `out` folder,
 which is where the release files are saved).
@@ -78,11 +79,11 @@
 When testing the extension during development, you don't have to build the
 extension each time you want to import an updated version to Chrome/Firefox.
 Instead, run `go run generateManifest.go {browser}` once, where `{browser}` is
-either `CHROMIUM` or `GECKO`, and this will generate a `manifest.json` file for
-the specified browser in the `src` directory. Now, you can load the `src` folder
-directly in the browser in order to import the extension, which removes the need
-to build it. When the `manifest.gjson` file is modified, you'll have to generate
-the manifest again.
+`CHROMIUM`, `GECKO` or `CHROMIUM_MV3`, and this will generate a `manifest.json`
+file for the specified browser in the `src` directory. Now, you can load the
+`src` folder directly in the browser in order to import the extension, which
+removes the need to build it. When the `manifest.gjson` file is modified,
+you'll have to generate the manifest again.
 
 To test translations, you might want to set your browser's locale. This section
 tells you how to set the locale in
diff --git a/release.bash b/release.bash
index 269bd4d..852e4f0 100644
--- a/release.bash
+++ b/release.bash
@@ -13,7 +13,8 @@
     -c, --channel  indicates the channel of the release. Can be "beta"
                    or "stable". Defaults to "stable".
     -b, --browser  indicates the target browser for the release. Can be
-                   "chromium" or "gecko". Defaults to "chromium".
+                   "chromium", "gecko" or "chromium_mv3".
+                   Defaults to "chromium".
 
 END
 }
@@ -54,7 +55,8 @@
   exit
 fi
 
-if [[ $browser != "chromium" && $browser != "gecko" ]]; then
+if [[ $browser != "chromium" && $browser != "gecko" &&
+      $browser != "chromium_mv3" ]]; then
   echo "browser parameter value is incorrect." >&2
   usage
   exit
diff --git a/src/sw.js b/src/sw.js
new file mode 100644
index 0000000..c90c5a6
--- /dev/null
+++ b/src/sw.js
@@ -0,0 +1,14 @@
+importScripts('common/common.js')
+
+// When the extension gets updated, set new options to their default value.
+chrome.runtime.onInstalled.addListener(details => {
+  if (details.reason == 'install' || details.reason == 'update') {
+    chrome.storage.sync.get(null, options => {
+      cleanUpOptions(options);
+    });
+  }
+});
+
+chrome.action.onClicked.addListener(_ => {
+  chrome.runtime.openOptionsPage();
+});
diff --git a/templates/manifest.gjson b/templates/manifest.gjson
index bbb65eb..3ee5587 100644
--- a/templates/manifest.gjson
+++ b/templates/manifest.gjson
@@ -1,8 +1,13 @@
 {
+#if defined(CHROMIUM || GECKO)
   "manifest_version": 2,
+#endif
+#if defined(CHROMIUM_MV3)
+  "manifest_version": 3,
+#endif
   "name": "__MSG_appName__",
   "version": "0",
-#if defined(CHROMIUM)
+#if defined(CHROMIUM || CHROMIUM_MV3)
   "version_name": "dirty",
 #endif
   "description": "__MSG_appDescription__",
@@ -43,14 +48,43 @@
     }
   ],
   "permissions": [
+#if defined(CHROMIUM || GECKO)
     "https://support.google.com/s/community*",
     "https://support.google.com/*/threads*",
     "https://support.google.com/*/thread/*",
+#endif
     "storage"
   ],
-  "web_accessible_resources": [
+#if defined(CHROMIUM_MV3)
+  "host_permissions": [
+    "https://support.google.com/s/community*",
+    "https://support.google.com/*/threads*",
+    "https://support.google.com/*/thread/*"
   ],
+#endif
+  "web_accessible_resources": [
+#if defined(CHROMIUM_MV3)
+    {
+      "resources": [
+#endif
+        "injections/profileindicator_inject.js",
+        "injections/profileindicator_inject.css",
+        "injections/ccdarktheme.css",
+        "injections/batchlock_inject.js"
+#if defined(CHROMIUM_MV3)
+      ],
+      "matches": [
+        "https://support.google.com/*"
+      ]
+    }
+#endif
+  ],
+#if defined(CHROMIUM || GECKO)
   "browser_action": {},
+#endif
+#if defined(CHROMIUM_MV3)
+  "action": {},
+#endif
 #if defined(CHROMIUM)
   "options_page": "options/options.html",
 #endif
@@ -59,6 +93,7 @@
     "open_in_tab": false
   },
   "background": {
+#if defined(CHROMIUM || GECKO)
 #if defined(CHROMIUM)
     "persistent": false,
 #endif
@@ -66,6 +101,10 @@
       "common/common.js",
       "background.js"
     ]
+#endif
+#if defined(CHROMIUM_MV3)
+    "service_worker": "sw.js"
+#endif
   },
 #if defined(GECKO)
   "browser_specific_settings": {