Bug 1121417: Change hiddenOneOffs search pref to use unichar type. r=gavin
authorChris <chrishood@eagles.ewu.edu>
Mon, 02 Mar 2015 14:00:45 -0800
changeset 261783 0bc001f799df5ab6d050dfd7b0bb1ec61b5e66a3
parent 261782 00c0d934ae62b206794fc5db8f5203ae88cf74ba
child 261784 d3c18534ce952079ca321869a429073e79f0361e
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgavin
bugs1121417
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1121417: Change hiddenOneOffs search pref to use unichar type. r=gavin
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
@@ -1199,24 +1199,20 @@
             addEngineList.appendChild(button);
           }
         }
 
         // Finally, build the list of one-off buttons.
         while (list.firstChild)
           list.firstChild.remove();
 
-        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
@@ -428,22 +428,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
   webapi.html
 
 [browser_405664.js]
 [browser_426329.js]
 skip-if = e10s # Bug ?????? - Test uses load event and checks event.target.
 [browser_483086.js]
@@ -29,16 +30,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.some(x => x == "FooDupe"), false,
      "Added engine is not present in hidden list.");
   is(hiddenOneOffs.some(x => x == "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,29 +131,36 @@ function* promiseOnLoad() {
         info("onLoadListener: " + aEvent.originalTarget.location);
         gBrowser.removeEventListener("load", onLoadListener, true);
         resolve(aEvent);
       }
     }, true);
   });
 }
 
-function promiseNewEngine(basename) {
+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);
-            Services.search.currentEngine = engine;
+            if (setAsCurrent) {
+              Services.search.currentEngine = engine;
+            }
             registerCleanupFunction(() => {
-              Services.search.currentEngine = current;
+              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();
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>