Bug 1121417 - Change hiddenOneOffs pref to use unichar type. r=gavin, a=lmandel
☠☠ backed out by 89b593b91e5e ☠ ☠
authorChris <chrishood@eagles.ewu.edu>
Fri, 06 Mar 2015 11:14:01 -0800
changeset 250302 513cff18abaa
parent 250301 eb42059e0728
child 250303 24f079da6625
push id4541
push userryanvm@gmail.com
push date2015-03-09 19:01 +0000
treeherdermozilla-beta@58b004077c10 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgavin, lmandel
bugs1121417
milestone37.0
Bug 1121417 - Change hiddenOneOffs pref to use unichar type. r=gavin, a=lmandel
browser/base/content/urlbarBindings.xml
browser/components/nsBrowserGlue.js
browser/components/preferences/in-content/search.xul
browser/components/preferences/search.xul
browser/components/search/test/browser.ini
browser/components/search/test/browser_hiddenOneOffs_cleanup.js
browser/components/search/test/browser_hiddenOneOffs_diacritics.js
browser/components/search/test/head.js
browser/components/search/test/testEngine_diacritics.xml
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -1154,24 +1154,20 @@
           }
         }
 
         // Finally, build the list of one-off buttons.
         while (list.firstChild)
           list.firstChild.remove();
         textbox._selectedButton = null;
 
-        let hiddenList;
-        try {
-          let pref =
-            Services.prefs.getCharPref("browser.search.hiddenOneOffs");
-          hiddenList = pref ? pref.split(",") : [];
-        } catch(e) {
-          hiddenList = [];
-        }
+        let Preferences =
+          Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
+        let pref = Preferences.get("browser.search.hiddenOneOffs");
+        let hiddenList = pref ? pref.split(",") : [];
 
         let currentEngineName = Services.search.currentEngine.name;
         let engines = Services.search.getVisibleEngines()
                               .filter(e => e.name != currentEngineName &&
                                            hiddenList.indexOf(e.name) == -1);
 
         let header = document.getAnonymousElementByAttribute(this, "anonid",
                                                              "search-panel-one-offs-header")
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -413,22 +413,23 @@ BrowserGlue.prototype = {
         });
 #endif
         break;
       case "browser-search-engine-modified":
         // Ensure we cleanup the hiddenOneOffs pref when removing
         // an engine, and that newly added engines are visible.
         if (data == "engine-added" || data == "engine-removed") {
           let engineName = subject.QueryInterface(Ci.nsISearchEngine).name;
-          let hiddenPref =
-            Services.prefs.getCharPref("browser.search.hiddenOneOffs");
-          let hiddenEngines = hiddenPref ? hiddenPref.split(",") : [];
-          hiddenEngines = hiddenEngines.filter(x => x !== engineName);
-          Services.prefs.setCharPref("browser.search.hiddenOneOffs",
-                                     hiddenEngines.join(","));
+          let Preferences =
+            Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
+          let pref = Preferences.get("browser.search.hiddenOneOffs");
+          let hiddenList = pref ? pref.split(",") : [];
+          hiddenList = hiddenList.filter(x => x !== engineName);
+          Preferences.set("browser.search.hiddenOneOffs",
+                          hiddenList.join(","));
         }
 
         if (data != "engine-default" && data != "engine-current") {
           break;
         }
         // Enforce that the search service's defaultEngine is always equal to
         // its currentEngine. The search service will notify us any time either
         // of them are changed (either by directly setting the relevant prefs,
--- a/browser/components/preferences/in-content/search.xul
+++ b/browser/components/preferences/in-content/search.xul
@@ -3,17 +3,17 @@
       <!-- Suggest -->
       <preference id="browser.search.suggest.enabled"
                   name="browser.search.suggest.enabled"
                   type="bool"/>
 
       <!-- One off providers -->
       <preference id="browser.search.hiddenOneOffs"
                   name="browser.search.hiddenOneOffs"
-                  type="string"/>
+                  type="unichar"/>
 
     </preferences>
 
     <script type="application/javascript"
             src="chrome://browser/content/preferences/in-content/search.js"/>
 
     <stringbundle id="engineManagerBundle" src="chrome://browser/locale/engineManager.properties"/>
 
--- a/browser/components/preferences/search.xul
+++ b/browser/components/preferences/search.xul
@@ -23,17 +23,17 @@
       <!-- Suggest -->
       <preference id="browser.search.suggest.enabled"
                   name="browser.search.suggest.enabled"
                   type="bool"/>
 
       <!-- One off providers -->
       <preference id="browser.search.hiddenOneOffs"
                   name="browser.search.hiddenOneOffs"
-                  type="string"/>
+                  type="unichar"/>
 
     </preferences>
 
     <script type="application/javascript" src="chrome://browser/content/preferences/search.js"/>
 
     <stringbundle id="engineManagerBundle" src="chrome://browser/locale/engineManager.properties"/>
 
     <!-- Default Search Engine -->
--- a/browser/components/search/test/browser.ini
+++ b/browser/components/search/test/browser.ini
@@ -4,16 +4,17 @@ support-files =
   426329.xml
   483086-1.xml
   483086-2.xml
   head.js
   opensearch.html
   test.html
   testEngine.src
   testEngine.xml
+  testEngine_diacritics.xml
   testEngine_dupe.xml
   testEngine_mozsearch.xml
 
 [browser_405664.js]
 [browser_426329.js]
 skip-if = e10s # Bug ?????? - Test uses load event and checks event.target.
 [browser_483086.js]
 [browser_addEngine.js]
@@ -28,16 +29,17 @@ skip-if = e10s # Bug ?????? - Test touch
 [browser_eBay.js]
 [browser_eBay_behavior.js]
 skip-if = e10s # Bug ?????? - some issue with progress listeners [JavaScript Error: "req.originalURI is null" {file: "chrome://mochitests/content/browser/browser/components/search/test/browser_bing_behavior.js" line: 127}]
 [browser_google.js]
 [browser_google_behavior.js]
 skip-if = e10s # Bug ?????? - some issue with progress listeners [JavaScript Error: "req.originalURI is null" {file: "chrome://mochitests/content/browser/browser/components/search/test/browser_bing_behavior.js" line: 127}]
 [browser_healthreport.js]
 [browser_hiddenOneOffs_cleanup.js]
+[browser_hiddenOneOffs_diacritics.js]
 [browser_private_search_perwindowpb.js]
 skip-if = e10s # Bug ?????? - Test uses load event and checks event.target.
 [browser_yahoo.js]
 [browser_yahoo_behavior.js]
 skip-if = e10s # Bug ?????? - some issue with progress listeners [JavaScript Error: "req.originalURI is null" {file: "chrome://mochitests/content/browser/browser/components/search/test/browser_bing_behavior.js" line: 127}]
 [browser_abouthome_behavior.js]
 skip-if = e10s || true # Bug ??????, Bug 1100301 - leaks windows until shutdown when --run-by-dir
 [browser_searchbar_openpopup.js]
--- a/browser/components/search/test/browser_hiddenOneOffs_cleanup.js
+++ b/browser/components/search/test/browser_hiddenOneOffs_cleanup.js
@@ -1,12 +1,11 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-const cachedPref = Services.prefs.getCharPref("browser.search.hiddenOneOffs");
 const testPref = "Foo,FooDupe";
 
 function promiseNewEngine(basename) {
   return new Promise((resolve, reject) => {
     info("Waiting for engine to be added: " + basename);
     Services.search.init({
       onInitComplete: function() {
         let url = getRootDirectory(gTestPath) + basename;
@@ -62,15 +61,39 @@ add_task(function* test_add() {
   is(hiddenOneOffs.length, 1,
      "hiddenOneOffs has the correct number of hidden engines present post add.");
   is(hiddenOneOffs.includes("FooDupe"), false,
      "Added engine is not present in hidden list.");
   is(hiddenOneOffs.includes("Foo"), true,
      "Adding an engine does not remove engines from hidden list.");
 });
 
+add_task(function* test_diacritics() {
+  const diacritic_engine = "Foo \u2661";
+  let Preferences =
+    Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
+
+  Preferences.set("browser.search.hiddenOneOffs", diacritic_engine);
+  yield promiseNewEngine("testEngine_diacritics.xml");
+
+  let hiddenOneOffs =
+    Preferences.get("browser.search.hiddenOneOffs").split(",");
+  is(hiddenOneOffs.some(x => x == diacritic_engine), false,
+     "Observer cleans up added hidden engines that include a diacritic.");
+
+  Preferences.set("browser.search.hiddenOneOffs", diacritic_engine);
+
+  info("Removing testEngine_diacritics.xml");
+  Services.search.removeEngine(Services.search.getEngineByName(diacritic_engine));
+
+  hiddenOneOffs =
+    Preferences.get("browser.search.hiddenOneOffs").split(",");
+  is(hiddenOneOffs.some(x => x == diacritic_engine), false,
+     "Observer cleans up removed hidden engines that include a diacritic.");
+});
+
 registerCleanupFunction(() => {
   info("Removing testEngine.xml");
   Services.search.removeEngine(Services.search.getEngineByName("Foo"));
   info("Removing testEngine_dupe.xml");
   Services.search.removeEngine(Services.search.getEngineByName("FooDupe"));
-  Services.prefs.setCharPref("browser.search.hiddenOneOffs", cachedPref);
+  Services.prefs.clearUserPref("browser.search.hiddenOneOffs");
 });
new file mode 100644
--- /dev/null
+++ b/browser/components/search/test/browser_hiddenOneOffs_diacritics.js
@@ -0,0 +1,74 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+// Tests that keyboard navigation in the search panel works as designed.
+
+const searchbar = document.getElementById("searchbar");
+const textbox = searchbar._textbox;
+const searchPopup = document.getElementById("PopupSearchAutoComplete");
+const searchIcon = document.getAnonymousElementByAttribute(searchbar, "anonid",
+                                                           "searchbar-search-button");
+
+const diacritic_engine = "Foo \u2661";
+
+let Preferences =
+  Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences;
+
+// Get an array of the one-off buttons.
+function getOneOffs() {
+  let oneOffs = [];
+  let oneOff =
+    document.getAnonymousElementByAttribute(searchPopup, "anonid",
+                                            "search-panel-one-offs");
+  for (oneOff = oneOff.firstChild; oneOff; oneOff = oneOff.nextSibling) {
+    if (oneOff.classList.contains("dummy"))
+      break;
+    oneOffs.push(oneOff);
+  }
+
+  return oneOffs;
+}
+
+add_task(function* init() {
+  let currentEngine = Services.search.currentEngine;
+  yield promiseNewEngine("testEngine_diacritics.xml", {setAsCurrent: false});
+  registerCleanupFunction(() => {
+    Services.search.currentEngine = currentEngine;
+    Services.prefs.clearUserPref("browser.search.hiddenOneOffs");
+  });
+});
+
+add_task(function* test_hidden() {
+  Preferences.set("browser.search.hiddenOneOffs", diacritic_engine);
+
+  let promise = promiseEvent(searchPopup, "popupshown");
+  info("Opening search panel");
+  EventUtils.synthesizeMouseAtCenter(searchIcon, {});
+  yield promise;
+
+  ok(!getOneOffs().some(x => x.getAttribute("tooltiptext") == diacritic_engine),
+     "Search engines with diacritics are hidden when added to hiddenOneOffs preference.");
+
+  promise = promiseEvent(searchPopup, "popuphidden");
+  info("Closing search panel");
+  EventUtils.synthesizeKey("VK_ESCAPE", {});
+  yield promise;
+});
+
+add_task(function* test_shown() {
+  Preferences.set("browser.search.hiddenOneOffs", "");
+
+  let promise = promiseEvent(searchPopup, "popupshown");
+  info("Opening search panel");
+  SimpleTest.executeSoon(() => {
+    EventUtils.synthesizeMouseAtCenter(searchIcon, {});
+  });
+  yield promise;
+
+  ok(getOneOffs().some(x => x.getAttribute("tooltiptext") == diacritic_engine),
+     "Search engines with diacritics are shown when removed from hiddenOneOffs preference.");
+
+  promise = promiseEvent(searchPopup, "popuphidden");
+  searchPopup.hidePopup();
+  yield promise;
+});
--- a/browser/components/search/test/head.js
+++ b/browser/components/search/test/head.js
@@ -131,16 +131,50 @@ function* promiseOnLoad() {
         info("onLoadListener: " + aEvent.originalTarget.location);
         gBrowser.removeEventListener("load", onLoadListener, true);
         resolve(aEvent);
       }
     }, true);
   });
 }
 
+function promiseNewEngine(basename, options = {}) {
+  return new Promise((resolve, reject) => {
+    //Default the setAsCurrent option to true.
+    let setAsCurrent =
+      options.setAsCurrent == undefined ? true : options.setAsCurrent;
+    info("Waiting for engine to be added: " + basename);
+    Services.search.init({
+      onInitComplete: function() {
+        let url = getRootDirectory(gTestPath) + basename;
+        let current = Services.search.currentEngine;
+        Services.search.addEngine(url, Ci.nsISearchEngine.TYPE_MOZSEARCH, "", false, {
+          onSuccess: function (engine) {
+            info("Search engine added: " + basename);
+            if (setAsCurrent) {
+              Services.search.currentEngine = engine;
+            }
+            registerCleanupFunction(() => {
+              if (setAsCurrent) {
+                Services.search.currentEngine = current;
+              }
+                Services.search.removeEngine(engine);
+                info("Search engine removed: " + basename);
+              });
+              resolve(engine);
+            },
+          onError: function (errCode) {
+            ok(false, "addEngine failed with error code " + errCode);
+            reject();
+          }
+        });
+      }
+    });
+  });
+}
 function promiseNewEngine(basename) {
   return new Promise((resolve, reject) => {
     info("Waiting for engine to be added: " + basename);
     Services.search.init({
       onInitComplete: function() {
         let url = getRootDirectory(gTestPath) + basename;
         let current = Services.search.currentEngine;
         Services.search.addEngine(url, Ci.nsISearchEngine.TYPE_MOZSEARCH, "", false, {
new file mode 100644
--- /dev/null
+++ b/browser/components/search/test/testEngine_diacritics.xml
@@ -0,0 +1,12 @@
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
+                       xmlns:moz="http://www.mozilla.org/2006/browser/search/">
+  <ShortName>Foo &#9825;</ShortName>
+  <Description>Engine whose ShortName contains non-BMP Unicode characters</Description>
+  <InputEncoding>utf-8</InputEncoding>
+  <Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC</Image>
+  <Url type="text/html" method="GET" template="http://mochi.test:8888/browser/browser/components/search/test/?search">
+    <Param name="test" value="{searchTerms}"/>
+  </Url>
+  <moz:SearchForm>http://mochi.test:8888/browser/browser/components/search/test/</moz:SearchForm>
+  <moz:Alias>diacriticalias</moz:Alias>
+</OpenSearchDescription>