Bug 1136139 - Fix collapsing of search suggestions when there are none. r=florian
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Wed, 29 Apr 2015 15:35:00 +0100
changeset 274073 e73e95394f91e114ea8321f8aa8c2802e3b8944f
parent 274072 606be3189b8533b1ea544a9c673cac2801404dbd
child 274074 e2c1e8294bfd1e16917cdba3f90434450b4f0853
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflorian
bugs1136139
milestone40.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 1136139 - Fix collapsing of search suggestions when there are none. r=florian
browser/base/content/urlbarBindings.xml
browser/components/search/content/search.xml
browser/components/search/test/browser_searchbar_openpopup.js
browser/themes/linux/searchbar.css
browser/themes/osx/searchbar.css
browser/themes/windows/searchbar.css
toolkit/components/search/nsSearchSuggestions.js
toolkit/content/widgets/autocomplete.xml
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -1144,17 +1144,21 @@ file, You can obtain one at http://mozil
           this.setAttribute("showonlysettings", "true");
 
           // Setting this with an xbl-inherited attribute gets overridden the
           // second time the user clicks the glass icon for some reason...
           tree.collapsed = true;
         }
         else {
           this.removeAttribute("showonlysettings");
-          tree.collapsed = false;
+          // Uncollapse as long as we have a tree with a view which has >= 1 row.
+          // The autocomplete binding itself will take care of uncollapsing later,
+          // if we currently have no rows but end up having some in the future
+          // when the search string changes
+          tree.collapsed = !tree.view || !tree.view.rowCount;
         }
 
         // Show the current default engine in the top header of the panel.
         this.updateHeader();
 
         // Update the 'Search for <keywords> with:" header.
         let headerSearchText =
           document.getAnonymousElementByAttribute(this, "anonid",
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -633,16 +633,17 @@
                    anonid="searchbar-textbox"
                    type="autocomplete"
                    flex="1"
                    autocompletepopup="PopupSearchAutoComplete"
                    autocompletesearch="search-autocomplete"
                    autocompletesearchparam="searchbar-history"
                    maxrows="10"
                    completeselectedindex="true"
+                   minresultsforpopup="0"
                    xbl:inherits="disabled,disableautocomplete,searchengine,src,newlines">
         <!--
         Empty <box> to properly position the icon within the autocomplete
         binding's anonymous children (the autocomplete binding positions <box>
         children differently)
         -->
         <xul:box>
           <xul:hbox class="searchbar-search-button-container">
@@ -1082,19 +1083,20 @@
         <body><![CDATA[
           let popup = this.popup;
           let list = document.getAnonymousElementByAttribute(popup, "anonid",
                                                              "search-panel-one-offs");
           let selectedButton = this.selectedButton;
           let buttons = this.getSelectableButtons(aCycleEngines);
 
           let suggestionsHidden;
-          if (!aSkipSuggestions && popup.hasAttribute("showonlysettings")) {
-            aSkipSuggestions = true;
-            suggestionsHidden = true;
+          if (!aSkipSuggestions) {
+            let suggestions = document.getAnonymousElementByAttribute(popup, "anonid", "tree");
+            suggestionsHidden = suggestions.getAttribute("collapsed") == "true";
+            aSkipSuggestions = suggestionsHidden;
           }
 
           // If the last suggestion is selected, DOWN selects the first button.
           if (!aSkipSuggestions && aForward &&
               popup.selectedIndex + 1 == popup.view.rowCount) {
             this.selectedButton = buttons[0];
             return false;
           }
--- a/browser/components/search/test/browser_searchbar_openpopup.js
+++ b/browser/components/search/test/browser_searchbar_openpopup.js
@@ -8,16 +8,17 @@ this._scriptLoader = Cc["@mozilla.org/mo
                      getService(Ci.mozIJSSubScriptLoader);
 this._scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js", ChromeUtils);
 
 const searchbar = document.getElementById("searchbar");
 const searchIcon = document.getAnonymousElementByAttribute(searchbar, "anonid", "searchbar-search-button");
 const goButton = document.getAnonymousElementByAttribute(searchbar, "anonid", "search-go-button");
 const textbox = searchbar._textbox;
 const searchPopup = document.getElementById("PopupSearchAutoComplete");
+const kValues = ["long text", "long text 2", "long text 3"];
 
 const isWindows = Services.appinfo.OS == "WINNT";
 const mouseDown = isWindows ? 2 : 1;
 const mouseUp = isWindows ? 4 : 2;
 const utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
                     .getInterface(Ci.nsIDOMWindowUtils);
 const scale = utils.screenPixelsPerCSSPixel;
 
@@ -39,16 +40,47 @@ function* synthesizeNativeMouseClick(aEl
 
     utils.sendNativeMouseEvent(x * scale, y * scale, mouseDown, 0, null);
     utils.sendNativeMouseEvent(x * scale, y * scale, mouseUp, 0, null);
   });
 }
 
 add_task(function* init() {
   yield promiseNewEngine("testEngine.xml");
+
+  // First cleanup the form history in case other tests left things there.
+  yield new Promise((resolve, reject) => {
+    info("cleanup the search history");
+    searchbar.FormHistory.update({op: "remove", fieldname: "searchbar-history"},
+                                 {handleCompletion: resolve,
+                                  handleError: reject});
+  });
+
+  yield new Promise((resolve, reject) => {
+    info("adding search history values: " + kValues);
+    let ops = kValues.map(value => { return {op: "add",
+                                             fieldname: "searchbar-history",
+                                             value: value}
+                                   });
+    searchbar.FormHistory.update(ops, {
+      handleCompletion: function() {
+        registerCleanupFunction(() => {
+          info("removing search history values: " + kValues);
+          let ops =
+            kValues.map(value => { return {op: "remove",
+                                           fieldname: "searchbar-history",
+                                           value: value}
+                                 });
+          searchbar.FormHistory.update(ops);
+        });
+        resolve();
+      },
+      handleError: reject
+    });
+  });
 });
 
 // Adds a task that shouldn't show the search suggestions popup.
 function add_no_popup_task(task) {
   add_task(function*() {
     let sawPopup = false;
     function listener() {
       sawPopup = true;
--- a/browser/themes/linux/searchbar.css
+++ b/browser/themes/linux/searchbar.css
@@ -114,28 +114,32 @@ searchbar[oneoffui] .search-go-button:-m
 }
 
 
 .search-panel-current-engine {
   border-top: none !important;
   -moz-box-align: center;
 }
 
-.search-panel-current-engine:not([showonlysettings]) {
+.search-panel-current-engine {
   border-bottom: 1px solid #ccc;
 }
 
 .search-panel-header {
   font-weight: normal;
   background-color: rgb(245, 245, 245);
   border-top: 1px solid #ccc;
   padding: 3px 5px;
   color: #666;
 }
 
+.search-panel-tree[collapsed=true] + .search-panel-header {
+  border-top: none;
+}
+
 .search-panel-current-input > label {
   margin: 0 0 !important;
 }
 
 .search-panel-input-value {
   color: black;
 }
 
--- a/browser/themes/osx/searchbar.css
+++ b/browser/themes/osx/searchbar.css
@@ -137,30 +137,34 @@ searchbar[oneoffui] .search-go-button:-m
   }
 }
 
 .search-panel-current-engine {
   border-top: none !important;
   border-radius: 4px 4px 0 0;
 }
 
-.search-panel-current-engine:not([showonlysettings]) {
+.search-panel-current-engine {
   border-bottom: 1px solid #ccc;
 }
 
 .search-panel-header {
   font-size: 10px;
   font-weight: normal;
   background-color: rgb(245, 245, 245);
   border-top: 1px solid #ccc;
   margin: 0;
   padding: 3px 6px;
   color: #666;
 }
 
+.search-panel-tree[collapsed=true] + .search-panel-header {
+  border-top: none;
+}
+
 .search-panel-current-input > label {
   margin: 0 0 !important;
 }
 
 .search-panel-input-value {
   color: black;
 }
 
--- a/browser/themes/windows/searchbar.css
+++ b/browser/themes/windows/searchbar.css
@@ -126,29 +126,33 @@ searchbar[oneoffui] .search-go-button:-m
 }
 
 
 .search-panel-current-engine {
   border-top: none !important;
   -moz-box-align: center;
 }
 
-.search-panel-current-engine:not([showonlysettings]) {
+.search-panel-current-engine {
   border-bottom: 1px solid #ccc;
 }
 
 .search-panel-header {
   font-weight: normal;
   background-color: rgb(245, 245, 245);
   border-top: 1px solid #ccc;
   margin: 0;
   padding: 3px 6px;
   color: #666;
 }
 
+.search-panel-tree[collapsed=true] + .search-panel-header {
+  border-top: none;
+}
+
 .search-panel-current-input > label {
   margin: 0 0 !important;
 }
 
 .search-panel-input-value {
   color: black;
 }
 
--- a/toolkit/components/search/nsSearchSuggestions.js
+++ b/toolkit/components/search/nsSearchSuggestions.js
@@ -69,23 +69,16 @@ SuggestAutoComplete.prototype = {
       // "comments" column values for suggestions starts as empty strings
       let comments = new Array(results.remote.length).fill("", 1);
       comments[0] = this._suggestionLabel;
       // now put the history results above the suggestions
       finalResults = finalResults.concat(results.remote);
       finalComments = finalComments.concat(comments);
     }
 
-    // If no result, add the search term so that the panel of the new UI is shown anyway.
-    if (!finalResults.length &&
-        Services.prefs.getBoolPref("browser.search.showOneOffButtons")) {
-      finalResults.push(results.term);
-      finalComments.push("");
-    }
-
     // Notify the FE of our new results
     this.onResultsReady(results.term, finalResults, finalComments, results.formHistoryResult);
   },
 
   /**
    * Notifies the front end of new results.
    * @param searchString  the user's query string
    * @param results       an array of results to the search
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -708,19 +708,19 @@
           if (!view)
             return;
           var rows = this.maxRows;
           if (!view.rowCount || (rows && view.rowCount < rows))
             rows = view.rowCount;
 
           var height = rows * bx.rowHeight;
 
-          if (height == 0)
+          if (height == 0) {
             this.tree.setAttribute("collapsed", "true");
-          else {
+          } else {
             if (this.tree.hasAttribute("collapsed"))
               this.tree.removeAttribute("collapsed");
 
             this.tree.setAttribute("height", height);
           }
           this.tree.setAttribute("hidescrollbar", view.rowCount <= rows);
         ]]>
         </body>