Bug 1489930 - Allow legacy extensions to specify a chrome URL as options page. r=philipp
authorGeoff Lankow <geoff@darktrojan.net>
Mon, 01 Oct 2018 15:39:45 +1300
changeset 33715 e0208c4fc4e22e157cddbe549ac3a5d6485aa459
parent 33714 c7cda013b0b433778d7f9a64b12823ab6c40f01c
child 33716 cde94d7d4f75f9be51eb71663493542718f82950
push id388
push userclokep@gmail.com
push dateMon, 28 Jan 2019 20:54:56 +0000
reviewersphilipp
bugs1489930
Bug 1489930 - Allow legacy extensions to specify a chrome URL as options page. r=philipp
mail/base/content/mailCore.js
mail/base/content/mailWindowOverlay.js
mail/components/extensions/schemas/legacy.json
--- a/mail/base/content/mailCore.js
+++ b/mail/base/content/mailCore.js
@@ -491,17 +491,17 @@ function openAddonsMgr(aView)
 }
 
 /**
  * Open a dialog with addon preferences.
  *
  * @option aURL  Chrome URL for the preferences XUL file of the addon.
  */
 function openAddonPrefs(aURL, aOptionsType) {
-  if (aOptionsType == 3) {
+  if (aOptionsType == "tab") {
     switchToTabHavingURI(aURL, true);
   } else {
     let instantApply = Services.prefs
                                .getBoolPref("browser.preferences.instantApply");
     let features = "chrome,titlebar,toolbar,centerscreen" +
                    (instantApply ? ",dialog=no" : ",modal");
 
     window.openDialog(aURL, "addonPrefs", features);
--- a/mail/base/content/mailWindowOverlay.js
+++ b/mail/base/content/mailWindowOverlay.js
@@ -8,17 +8,19 @@ ChromeUtils.import("resource:///modules/
 ChromeUtils.import("resource:///modules/MailConsts.jsm");
 ChromeUtils.import("resource:///modules/MailServices.jsm");
 ChromeUtils.import("resource:///modules/MailUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/PluralForm.jsm");
 ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 
 ChromeUtils.defineModuleGetter(this, "BrowserToolboxProcess", "resource://devtools/client/framework/ToolboxProcess.jsm");
-ChromeUtils.defineModuleGetter(this, "ScratchpadManager","resource://devtools/client/scratchpad/scratchpad-manager.jsm");
+ChromeUtils.defineModuleGetter(this, "ScratchpadManager", "resource://devtools/client/scratchpad/scratchpad-manager.jsm");
+ChromeUtils.defineModuleGetter(this, "ExtensionParent", "resource://gre/modules/ExtensionParent.jsm");
+ChromeUtils.defineModuleGetter(this, "ExtensionSupport", "resource:///modules/extensionSupport.jsm");
 Object.defineProperty(this, "HUDService", {
   get: function HUDService_getter() {
     let { devtools } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", null);
     return devtools.require("devtools/client/webconsole/hudservice").HUDService;
   },
   configurable: true,
   enumerable: true
 });
@@ -3735,32 +3737,54 @@ async function initAddonPrefsMenu(aMenup
   // "no add-on prefs", which is the only disabled element. Above this element
   // there may be further items that we want to preserve.
   let noPrefsElem = aMenupopup.querySelector('[disabled="true"]');
   while (aMenupopup.lastChild != noPrefsElem) {
     aMenupopup.lastChild.remove();
   }
 
   // Enumerate all enabled addons with URL to XUL document with prefs.
-  let addonsFound = await AddonManager.getAddonsByTypes(["extension"]);
-  addonsFound = addonsFound.filter(addon => !addon.userDisabled && !addon.appDisabled &&
-                                            !addon.softDisabled && addon.optionsURL &&
-                                            (addon.optionsType === null || addon.optionsType == 3));
+  let addonsFound = [];
+  for (let addon of await AddonManager.getAddonsByTypes(["extension"])) {
+    if (addon.userDisabled || addon.appDisabled || addon.softDisabled) {
+      continue;
+    }
+    if (addon.optionsURL && (addon.optionsType === null || addon.optionsType == 3)) {
+      addonsFound.push({
+        addon,
+        optionsURL: addon.optionsURL,
+        optionsOpenInTab: addon.optionsType == 3,
+      });
+    }
+    if (ExtensionSupport.loadedLegacyExtensions.has(addon.id)) {
+      let webextension = ExtensionParent.GlobalManager.getExtension(addon.id);
+      let legacy = webextension.manifest.legacy;
+      if (typeof legacy == "boolean" || !legacy.options || !legacy.options.page) {
+        continue;
+      }
+      addonsFound.push({
+        addon,
+        optionsURL: legacy.options.page,
+        optionsOpenInTab: legacy.options.open_in_tab,
+      });
+    }
+  }
 
   // Populate the menu with addon names and icons.
   // Note: Having the following code in the getAddonsByTypes() async callback
   // above works on Windows and Linux but doesn't work on Mac, see bug 1419145.
   if (addonsFound.length > 0) {
-    addonsFound.sort((a,b) => a.name.localeCompare(b.name));
-    for (let addon of addonsFound) {
+    addonsFound.sort((a, b) => a.addon.name.localeCompare(b.addon.name));
+    for (let { addon, optionsURL, optionsOpenInTab } of addonsFound) {
       let newItem = document.createElement("menuitem");
       newItem.setAttribute("label", addon.name);
-      newItem.setAttribute("value", addon.optionsURL);
-      if (addon.optionsType)
-        newItem.setAttribute("optionsType", addon.optionsType);
+      newItem.setAttribute("value", optionsURL);
+      if (optionsOpenInTab) {
+        newItem.setAttribute("optionsType", "tab");
+      }
       let iconURL = addon.iconURL || addon.icon64URL;
       if (iconURL) {
         newItem.setAttribute("class", "menuitem-iconic");
         newItem.setAttribute("image", iconURL);
       }
       aMenupopup.appendChild(newItem);
     }
     noPrefsElem.setAttribute("collapsed", "true");
--- a/mail/components/extensions/schemas/legacy.json
+++ b/mail/components/extensions/schemas/legacy.json
@@ -1,16 +1,38 @@
 [
   {
     "namespace": "manifest",
     "types": [
       {
         "$extend": "WebExtensionManifest",
         "properties": {
           "legacy": {
-            "type": "boolean",
-            "optional": true
+            "optional": true,
+            "choices": [
+              {
+                "type": "boolean",
+                "optional": true
+              },
+              {
+                "type": "object",
+                "properties": {
+                  "options": {
+                    "type": "object",
+                    "properties": {
+                      "page": {
+                        "type": "string"
+                      },
+                      "open_in_tab": {
+                        "type": "boolean",
+                        "optional": true
+                      }
+                    }
+                  }
+                }
+              }
+            ]
           }
         }
       }
     ]
   }
 ]