Bug 1162140 - Allow user to select search suggestions in Awesome Bar. r=adw
authorMarco Bonardo <mbonardo@mozilla.com>
Thu, 11 Jun 2015 13:20:46 -0700
changeset 266782 e420871145cbc90e2574696e6060b02d799d1c57
parent 266781 eeeaa094d312822a29f653676727b690948c1025
child 266783 8dd26972a9d862484d1cecb519a012c74adbecb8
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-esr52@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersadw
bugs1162140
milestone41.0a1
Bug 1162140 - Allow user to select search suggestions in Awesome Bar. r=adw
toolkit/components/places/UnifiedComplete.js
toolkit/content/autocomplete.css
toolkit/content/widgets/autocomplete.xml
toolkit/locales/en-US/chrome/global/autocomplete.properties
--- a/toolkit/components/places/UnifiedComplete.js
+++ b/toolkit/components/places/UnifiedComplete.js
@@ -961,36 +961,37 @@ Search.prototype = {
     let alias = this._searchTokens[0];
     let match = yield PlacesSearchAutocompleteProvider.findMatchByAlias(alias);
     if (!match)
       return false;
 
     match.engineAlias = alias;
     let query = this._searchTokens.slice(1).join(" ");
 
-    yield this._addSearchEngineMatch(match, query);
+    this._addSearchEngineMatch(match, query);
     return true;
   },
 
   _matchCurrentSearchEngine: function* () {
     let match = yield PlacesSearchAutocompleteProvider.getDefaultMatch();
     if (!match)
       return;
 
     let query = this._originalSearchString;
-
-    yield this._addSearchEngineMatch(match, query);
+    this._addSearchEngineMatch(match, query);
   },
 
-  _addSearchEngineMatch: function* (match, query) {
+  _addSearchEngineMatch(match, query, suggestion) {
     let actionURLParams = {
       engineName: match.engineName,
       input: this._originalSearchString,
       searchQuery: query,
     };
+    if (suggestion)
+      actionURLParams.searchSuggestion = suggestion;
     if (match.engineAlias) {
       actionURLParams.alias = match.engineAlias;
     }
     let value = makeActionURL("searchengine", actionURLParams);
 
     this._addMatch({
       value: value,
       comment: match.engineName,
--- a/toolkit/content/autocomplete.css
+++ b/toolkit/content/autocomplete.css
@@ -6,8 +6,12 @@
 @namespace html url("http://www.w3.org/1999/xhtml");
 
 /* Apply crisp rendering for favicons at exactly 2dppx resolution */
 @media (resolution: 2dppx) {
   .ac-site-icon {
     image-rendering: -moz-crisp-edges;
   }
 }
+
+richlistitem > .ac-title-box > .ac-title > .ac-comment:not([selected]) > html|span.ac-selected-text {
+  display: none;
+}
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -1534,21 +1534,20 @@ extends="chrome://global/content/binding
 
               if (match) {
                 // "%S" doesn't have a numerical number in it, but will always
                 // be assumed to be 1. Furthermore, the input string specifies
                 // these with a 1-based index, but we want a 0-based index.
                 let index = (match[1] || 1) - 1;
 
                 if (index >= 0 && index < aReplacements.length) {
-                  let replacement = aReplacements[index];
-                  pairs.push([...replacement]);
+                  pairs.push([...aReplacements[index]]);
                 }
               } else {
-                pairs.push([part, false]);
+                pairs.push([part]);
               }
             }
 
             return pairs;
           ]]>
         </body>
       </method>
 
@@ -1567,18 +1566,25 @@ extends="chrome://global/content/binding
           // Get rid of all previous text
           while (aDescriptionElement.hasChildNodes())
             aDescriptionElement.firstChild.remove();
 
           for (let [text, emphasise] of aTextPairs) {
             if (emphasise) {
               let span = aDescriptionElement.appendChild(
                 document.createElementNS("http://www.w3.org/1999/xhtml", "span"));
-              span.className = "ac-emphasize-text";
               span.textContent = text;
+              switch(emphasise) {
+                case "match":
+                  span.className = "ac-emphasize-text";
+                  break;
+                case "selected":
+                  span.className = "ac-selected-text";
+                  break;
+              }
             } else {
               aDescriptionElement.appendChild(document.createTextNode(text));
             }
           }
           ]]>
         </body>
       </method>
 
@@ -1624,37 +1630,49 @@ extends="chrome://global/content/binding
             if (action.type == "switchtab") {
               this.classList.add("overridable-action");
               displayUrl = action.params.url;
               let desc = this._stringBundle.GetStringFromName("switchToTab");
               this._setUpDescription(this._action, desc, true);
             } else if (action.type == "searchengine") {
               emphasiseUrl = false;
 
-              let sourceStr = this._stringBundle.GetStringFromName("searchWithEngineForQuery");
-              title = this._generateEmphasisPairs(sourceStr, [
-                                                    [action.params.engineName, false],
-                                                    [action.params.searchQuery, true]
+              // The order here is not localizable, we default to appending
+              // "- Search with Engine" to the search string, to be able to
+              // properly generate emphasis pairs. That said, no localization
+              // changed the order while it was possible, so doesn't look like
+              // there's a strong need for that.
+              let {engineName, searchSuggestion, searchQuery} = action.params;
+              let engineStr = "- " +
+                this._stringBundle.formatStringFromName("searchWithEngine",
+                                                        [engineName], 1);
+              let suggestedPart = "";
+              if (searchSuggestion) {
+                suggestedPart = searchSuggestion.substr(searchQuery.length);
+              }
+              title = this._generateEmphasisPairs(`%1$S${suggestedPart} %2$S`, [
+                                                    [searchQuery, "match"],
+                                                    [engineStr, "selected"],
                                                   ]);
               // If this is a default search match, we remove the image so we
               // can style it ourselves with a generic search icon.
               // We don't do this when matching an aliased search engine,
               // because the icon helps with recognising which engine will be
               // used (when using the default engine, we don't need that
               // recognition).
               if (!action.params.alias) {
                 this.removeAttribute("image");
               }
             } else if (action.type == "visiturl") {
               emphasiseUrl = false;
               displayUrl = action.params.url;
 
               let sourceStr = this._stringBundle.GetStringFromName("visitURL");
               title = this._generateEmphasisPairs(sourceStr, [
-                                                    [displayUrl, true],
+                                                    [displayUrl, "match"],
                                                   ]);
             }
 
             // Remove the "action" substring so that the correct style, if any,
             // is applied below.
             types.delete("action");
           }
 
@@ -1674,17 +1692,17 @@ extends="chrome://global/content/binding
           }
 
           // Check if we have an auto-fill URL
           if (types.has("autofill")) {
             emphasiseUrl = false;
 
             let sourceStr = this._stringBundle.GetStringFromName("visitURL");
             title = this._generateEmphasisPairs(sourceStr, [
-                                                 [displayUrl, true],
+                                                 [displayUrl, "match"],
                                                 ]);
 
             types.delete("autofill");
           }
 
           type = [...types].join(" ");
 
           // If we have a tag match, show the tags and icon
--- a/toolkit/locales/en-US/chrome/global/autocomplete.properties
+++ b/toolkit/locales/en-US/chrome/global/autocomplete.properties
@@ -1,17 +1,12 @@
 # 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/.
 
 # LOCALIZATION NOTE (searchWithEngine): %S will be replaced with
 # the search engine provider's name. This format was chosen because
 # the provider can also end with "Search" (e.g.: MSN Search).
 searchWithEngine = Search with %S
-# LOCALIZATION NOTE (searchWithEngineForQuery):
-# %1$S is the search engine's name, %2$S is the search query.
-# This format was chosen because the provider can also end with "Search"
-# (e.g.: MSN Search).
-searchWithEngineForQuery = %2$S — Search with %1$S 
 switchToTab = Switch to tab
 # LOCALIZATION NOTE (visitURL):
 # %S is the URL to visit.
 visitURL = Visit %S