Bug 1427317 - Allow addition of search engines from XML file and removal in general pane in preferences. r=Paenglab a=jorgk
authorJorg K <jorgk@jorgk.com>
Sat, 23 Mar 2019 18:49:55 +0100
changeset 33955 4fa819fdd79f2e0f046cec2a0cbdcb77e6c8c7d5
parent 33954 43530adfd6da555e8c66d9ede229644c486ea8b9
child 33956 9f66c4248a572d695c43701b64e757f9d27e4db0
push id2392
push usermozilla@jorgk.com
push dateSat, 23 Mar 2019 18:54:09 +0000
treeherdercomm-beta@8a987f6e6350 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersPaenglab, jorgk
bugs1427317
Bug 1427317 - Allow addition of search engines from XML file and removal in general pane in preferences. r=Paenglab a=jorgk
mail/components/preferences/general.inc.xul
mail/components/preferences/general.js
--- a/mail/components/preferences/general.inc.xul
+++ b/mail/components/preferences/general.inc.xul
@@ -24,20 +24,28 @@
                   oncommand="gGeneralPane.restoreDefaultStartPage();">
             <observes element="mailnewsStartPageUrl" attribute="disabled"/>
           </button>
         </hbox>
     </groupbox>
 
     <groupbox>
       <label><html:h2 >&defaultSearchEngine.label;</html:h2></label>
-      <hbox>
+      <hbox align="center">
         <menulist id="defaultWebSearch">
           <menupopup id="defaultWebSearchPopup"/>
         </menulist>
+        <button id="addSearchEngine"
+                label="+"
+                style="min-width: 2.5em;"
+                oncommand="gGeneralPane.addSearchEngine();"/>
+        <button id="removeSearchEngine"
+                label="-"
+                style="min-width: 2.5em;"
+                oncommand="gGeneralPane.removeSearchEngine();"/>
       </hbox>
     </groupbox>
 
     <groupbox>
       <label><html:h2>&newMessagesArrive.label;</html:h2></label>
 #ifdef XP_MACOSX
       <hbox align="center">
         <description flex="1">&changeDockIconOptions.label;</description>
--- a/mail/components/preferences/general.js
+++ b/mail/components/preferences/general.js
@@ -203,34 +203,100 @@ var gGeneralPane = {
     // The button does not exist on all platforms.
     let customizeAlertButton = document.getElementById("customizeMailAlert");
     if (customizeAlertButton) {
       customizeAlertButton.disabled = !Preferences.get("mail.biff.show_alert").value;
     }
   },
 
   updateWebSearch() {
+    let self = this;
     Services.search.init().then(async () => {
       let defaultEngine = await Services.search.getDefault();
       let engineList = document.getElementById("defaultWebSearch");
       for (let engine of await Services.search.getVisibleEngines()) {
         let item = engineList.appendItem(engine.name);
         item.engine = engine;
         item.className = "menuitem-iconic";
         item.setAttribute("image", engine.iconURI ? engine.iconURI.spec :
           "resource://gre-resources/broken-image.png"
         );
         if (engine == defaultEngine) {
           engineList.selectedItem = item;
         }
       }
+      self.defaultEngines = await Services.search.getDefaultEngines();
+      self.updateRemoveButton();
 
-      engineList.addEventListener("command", () => {
-        Services.search.setDefault(engineList.selectedItem.engine);
+      engineList.addEventListener("command", async () => {
+        await Services.search.setDefault(engineList.selectedItem.engine);
+        self.updateRemoveButton();
       });
     });
   },
+
+  // Caches the default engines so we only retrieve them once.
+  defaultEngines: null,
+
+  async updateRemoveButton() {
+    let engineList = document.getElementById("defaultWebSearch");
+    let removeButton = document.getElementById("removeSearchEngine");
+    if (this.defaultEngines.includes(await Services.search.getDefault())) {
+      // Don't allow deletion of a default engine (saves us having a 'restore' button).
+      removeButton.disabled = true;
+    } else {
+      // Don't allow removal of last engine. This shouldn't happen since there should
+      // always be default engines.
+      removeButton.disabled = engineList.itemCount <= 1;
+    }
+  },
+
+  addSearchEngine() {
+    let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+    fp.init(window, "", Ci.nsIFilePicker.modeOpen);
+
+    // Filter on XML files only
+    fp.appendFilter("XML", "*.xml");
+
+    fp.open(async rv => {
+      if (rv != Ci.nsIFilePicker.returnOK || !fp.file) {
+        return;
+      }
+      let engineAdd = fp.fileURL.spec;
+      let engine = await Services.search.addEngine(engineAdd, null, false);
+
+      // Add new engine to the list.
+      let engineList = document.getElementById("defaultWebSearch");
+
+      let item = engineList.appendItem(engine.name);
+      item.engine = engine;
+      item.className = "menuitem-iconic";
+      item.setAttribute(
+        "image", engine.iconURI ? engine.iconURI.spec :
+                 "resource://gre-resources/broken-image.png"
+      );
+
+      this.updateRemoveButton();
+    });
+  },
+
+  async removeSearchEngine() {
+    // Deletes the current engine. Firefox does a better job since it
+    // shows all the engines in the list. But better than nothing.
+    let defaultEngine = await Services.search.getDefault();
+    let engineList = document.getElementById("defaultWebSearch");
+    for (let i = 0; i < engineList.itemCount; i++) {
+      let item = engineList.getItemAtIndex(i);
+      if (item.engine == defaultEngine) {
+        await Services.search.removeEngine(item.engine);
+        item.remove();
+        engineList.selectedIndex = 0;
+        this.updateRemoveButton();
+        break;
+      }
+    }
+  },
 };
 
 Preferences.get("mailnews.start_page.enabled").on("change", gGeneralPane.updateStartPage);
 if (AppConstants.platform != "macosx") {
   Preferences.get("mail.biff.show_alert").on("change", gGeneralPane.updateCustomizeAlert);
 }