Let features request optional host permissions

Sometimes a feature requires additional host permissions to work. This
change allows features to request this.

This change has changed the structure of requiredOptPermissions in the
optionsPrototype.json5 file from being an array of string permissions to
being an object of type chrome.permissions.Permissions (an object
containing property permissions (an array of (string) permissions, as
before) and property origins (an array of (string) hosts).

Bug: twpowertools:86, twpowertools:87
Change-Id: Iacdc6f928876942e213488b12e12f950da7b7c05
diff --git a/src/options/optionsCommon.js b/src/options/optionsCommon.js
index 99874e5..f0b20bf 100644
--- a/src/options/optionsCommon.js
+++ b/src/options/optionsCommon.js
@@ -1,5 +1,5 @@
 import {getExtVersion, isProdVersion} from '../common/extUtils.js';
-import {ensureOptPermissions, grantedOptPermissions, missingPermissions} from '../common/optionsPermissions.js';
+import {ensureOptPermissions, grantedOptPermissions, isPermissionsObjectEmpty, missingPermissions} from '../common/optionsPermissions.js';
 import {cleanUpOptions, optionsPrototype, specialOptions} from '../common/optionsUtils.js';
 
 import optionsPage from './optionsPage.json5';
@@ -250,9 +250,10 @@
             for (const mode of threadPageModes) {
               let modeOption = document.createElement('option');
               modeOption.value = mode;
-              modeOption.textContent =
-                  chrome.i18n.getMessage('options_interopthreadpage_mode_' + mode);
-              if (items.interopthreadpage_mode == mode) modeOption.selected = true;
+              modeOption.textContent = chrome.i18n.getMessage(
+                  'options_interopthreadpage_mode_' + mode);
+              if (items.interopthreadpage_mode == mode)
+                modeOption.selected = true;
               select.appendChild(modeOption);
             }
 
@@ -293,7 +294,7 @@
     grantedOptPermissions()
         .then(grantedPerms => {
           for (const [opt, optMeta] of Object.entries(optionsPrototype)) {
-            if (!optMeta.requiredOptPermissions?.length || !isOptionShown(opt))
+            if (!optMeta.requiredOptPermissions || !isOptionShown(opt))
               continue;
 
             let warningLabel = document.querySelector(
@@ -346,8 +347,7 @@
               let shownHeaderMessage = false;
               missingPermissions(opt, grantedPerms)
                   .then(missingPerms => {
-                    console.log(missingPerms);
-                    if (missingPerms.length > 0) {
+                    if (!isPermissionsObjectEmpty(missingPerms)) {
                       checkbox.indeterminate = true;
                       checkbox.setAttribute(kClickShouldEnableFeat, '');