Bug 1034381 - Enhance previous searches in awesomebar dropdown by removing URL. r=mak

This commit is contained in:
Paolo Amadini 2014-08-01 16:41:32 +01:00
parent 9e803c070a
commit 26204314d1
5 changed files with 126 additions and 38 deletions

View File

@ -22,25 +22,25 @@ const DEFAULT_BEHAVIOR = 0;
const PREF_BRANCH = "browser.urlbar.";
// Prefs are defined as [pref name, default value].
const PREF_ENABLED = [ "autocomplete.enabled", true ];
const PREF_AUTOFILL = [ "autoFill", true ];
const PREF_AUTOFILL_TYPED = [ "autoFill.typed", true ];
const PREF_AUTOFILL_PRIORITY = [ "autoFill.priority", true ];
const PREF_DELAY = [ "delay", 50 ];
const PREF_BEHAVIOR = [ "matchBehavior", MATCH_BOUNDARY_ANYWHERE ];
const PREF_DEFAULT_BEHAVIOR = [ "default.behavior", DEFAULT_BEHAVIOR ];
const PREF_EMPTY_BEHAVIOR = [ "default.behavior.emptyRestriction",
Ci.mozIPlacesAutoComplete.BEHAVIOR_HISTORY |
Ci.mozIPlacesAutoComplete.BEHAVIOR_TYPED ];
const PREF_FILTER_JS = [ "filter.javascript", true ];
const PREF_MAXRESULTS = [ "maxRichResults", 25 ];
const PREF_RESTRICT_HISTORY = [ "restrict.history", "^" ];
const PREF_RESTRICT_BOOKMARKS = [ "restrict.bookmark", "*" ];
const PREF_RESTRICT_TYPED = [ "restrict.typed", "~" ];
const PREF_RESTRICT_TAG = [ "restrict.tag", "+" ];
const PREF_RESTRICT_SWITCHTAB = [ "restrict.openpage", "%" ];
const PREF_MATCH_TITLE = [ "match.title", "#" ];
const PREF_MATCH_URL = [ "match.url", "@" ];
const PREF_ENABLED = [ "autocomplete.enabled", true ];
const PREF_AUTOFILL = [ "autoFill", true ];
const PREF_AUTOFILL_TYPED = [ "autoFill.typed", true ];
const PREF_AUTOFILL_SEARCHENGINES = [ "autoFill.searchEngines", true ];
const PREF_DELAY = [ "delay", 50 ];
const PREF_BEHAVIOR = [ "matchBehavior", MATCH_BOUNDARY_ANYWHERE ];
const PREF_DEFAULT_BEHAVIOR = [ "default.behavior", DEFAULT_BEHAVIOR ];
const PREF_EMPTY_BEHAVIOR = [ "default.behavior.emptyRestriction",
Ci.mozIPlacesAutoComplete.BEHAVIOR_HISTORY |
Ci.mozIPlacesAutoComplete.BEHAVIOR_TYPED ];
const PREF_FILTER_JS = [ "filter.javascript", true ];
const PREF_MAXRESULTS = [ "maxRichResults", 25 ];
const PREF_RESTRICT_HISTORY = [ "restrict.history", "^" ];
const PREF_RESTRICT_BOOKMARKS = [ "restrict.bookmark", "*" ];
const PREF_RESTRICT_TYPED = [ "restrict.typed", "~" ];
const PREF_RESTRICT_TAG = [ "restrict.tag", "+" ];
const PREF_RESTRICT_SWITCHTAB = [ "restrict.openpage", "%" ];
const PREF_MATCH_TITLE = [ "match.title", "#" ];
const PREF_MATCH_URL = [ "match.url", "@" ];
// Match type constants.
// These indicate what type of search function we should be using.
@ -62,11 +62,14 @@ const QUERYTYPE_AUTOFILL_URL = 3;
// "comment" back into the title and the tag.
const TITLE_TAGS_SEPARATOR = " \u2013 ";
// This separator identifies the search engine name in the title.
const TITLE_SEARCH_ENGINE_SEPARATOR = " \u00B7\u2013\u00B7 ";
// Telemetry probes.
const TELEMETRY_1ST_RESULT = "PLACES_AUTOCOMPLETE_1ST_RESULT_TIME_MS";
// The default frecency value used when inserting priority results.
const FRECENCY_PRIORITY_DEFAULT = 1000;
// The default frecency value used when inserting search engine results.
const FRECENCY_SEARCHENGINES_DEFAULT = 1000;
// Sqlite result row index constants.
const QUERYINDEX_QUERYTYPE = 0;
@ -359,7 +362,7 @@ XPCOMUtils.defineLazyGetter(this, "Prefs", () => {
store.enabled = prefs.get(...PREF_ENABLED);
store.autofill = prefs.get(...PREF_AUTOFILL);
store.autofillTyped = prefs.get(...PREF_AUTOFILL_TYPED);
store.autofillPriority = prefs.get(...PREF_AUTOFILL_PRIORITY);
store.autofillSearchEngines = prefs.get(...PREF_AUTOFILL_SEARCHENGINES);
store.delay = prefs.get(...PREF_DELAY);
store.matchBehavior = prefs.get(...PREF_BEHAVIOR);
store.filterJavaScript = prefs.get(...PREF_FILTER_JS);
@ -629,8 +632,12 @@ Search.prototype = {
this._pendingQuery = true;
TelemetryStopwatch.start(TELEMETRY_1ST_RESULT);
// Since we call the synchronous parseSubmissionURL function later, we must
// wait for the initialization of PlacesSearchAutocompleteProvider first.
yield PlacesSearchAutocompleteProvider.ensureInitialized();
// For any given search, we run many queries:
// 1) priority domains
// 1) search engine domains
// 2) inline completion
// 3) keywords (this._keywordQuery)
// 4) adaptive learning (this._adaptiveQuery)
@ -649,7 +656,7 @@ Search.prototype = {
PlacesUtils.bookmarks.getURIForKeyword(this._searchTokens[0])) {
queries.unshift(this._keywordQuery);
} else if (this._searchTokens.length == 1) {
yield this._matchPriorityUrl();
yield this._matchSearchEngineUrl();
}
if (this._shouldAutofill) {
@ -700,22 +707,21 @@ Search.prototype = {
}
}),
_matchPriorityUrl: function* () {
if (!Prefs.autofillPriority)
_matchSearchEngineUrl: function* () {
if (!Prefs.autofillSearchEngines)
return;
// Handle priority matches for search engine domains.
let priorityMatch =
yield PlacesSearchAutocompleteProvider.findMatchByToken(this._searchString);
if (priorityMatch) {
let match = yield PlacesSearchAutocompleteProvider.findMatchByToken(
this._searchString);
if (match) {
this._result.setDefaultIndex(0);
this._addFrecencyMatch({
value: priorityMatch.token,
comment: priorityMatch.engineName,
icon: priorityMatch.iconUrl,
value: match.token,
comment: match.engineName,
icon: match.iconUrl,
style: "priority-search",
finalCompleteValue: priorityMatch.url,
frecency: FRECENCY_PRIORITY_DEFAULT
finalCompleteValue: match.url,
frecency: FRECENCY_SEARCHENGINES_DEFAULT
});
}
},
@ -754,6 +760,30 @@ Search.prototype = {
this._frecencyMatches.sort((a, b) => a.frecency - b.frecency);
},
_maybeRestyleSearchMatch: function (match) {
// Return if the URL does not represent a search result.
let parseResult =
PlacesSearchAutocompleteProvider.parseSubmissionURL(match.value);
if (!parseResult) {
return;
}
// Do not apply the special style if the user is doing a search from the
// location bar but the entered terms match an irrelevant portion of the
// URL. For example, "https://www.google.com/search?q=terms&client=firefox"
// when searching for "Firefox".
let terms = parseResult.terms.toLowerCase();
if (this._searchTokens.length > 0 &&
this._searchTokens.every(token => terms.indexOf(token) == -1)) {
return;
}
// Use the special separator that the binding will use to style the item.
match.style = "search " + match.style;
match.comment = parseResult.terms + TITLE_SEARCH_ENGINE_SEPARATOR +
parseResult.engineName;
},
_addMatch: function (match) {
let notifyResults = false;
@ -779,10 +809,19 @@ Search.prototype = {
this._usedPlaceIds.add(match.placeId);
this._usedURLs.add(urlMapKey);
if (!match.style) {
match.style = "favicon";
}
// Restyle past searches, unless they are bookmarks or special results.
if (match.style == "favicon") {
this._maybeRestyleSearchMatch(match);
}
this._result.appendMatch(match.value,
match.comment,
match.icon || PlacesUtils.favicons.defaultFavicon.spec,
match.style || "favicon",
match.style,
match.finalCompleteValue);
notifyResults = true;
}

View File

@ -17,6 +17,8 @@ let (commonFile = do_get_file("../head_common.js", false)) {
// Put any other stuff relative to this test folder below.
const TITLE_SEARCH_ENGINE_SEPARATOR = " \u00B7\u2013\u00B7 ";
function run_test() {
run_next_test();
}
@ -147,9 +149,11 @@ function* check_autocomplete(test) {
if (matches[j] == undefined)
continue;
let { uri, title, tags } = matches[j];
let { uri, title, tags, searchEngine } = matches[j];
if (tags)
title += " \u2013 " + tags.sort().join(", ");
if (searchEngine)
title += TITLE_SEARCH_ENGINE_SEPARATOR + searchEngine;
do_log_info("Checking against expected '" + uri.spec + "', '" + title + "'...");
// Got a match on both uri and title?

View File

@ -0,0 +1,25 @@
/* 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/. */
add_task(function* test_searchEngine() {
Services.search.addEngineWithDetails("SearchEngine", "", "", "",
"GET", "http://s.example.com/search");
let engine = Services.search.getEngineByName("SearchEngine");
engine.addParam("q", "{searchTerms}", null);
do_register_cleanup(() => Services.search.removeEngine(engine));
let uri1 = NetUtil.newURI("http://s.example.com/search?q=Terms&client=1");
let uri2 = NetUtil.newURI("http://s.example.com/search?q=Terms&client=2");
yield promiseAddVisits({ uri: uri1, title: "Terms - SearchEngine Search" });
addBookmark({ uri: uri2, title: "Terms - SearchEngine Search" });
do_log_info("Past search terms should be styled, unless bookmarked");
yield check_autocomplete({
search: "term",
matches: [ { uri: uri1, title: "Terms", searchEngine: "SearchEngine" },
{ uri: uri2, title: "Terms - SearchEngine Search" } ]
});
yield cleanup();
});

View File

@ -23,6 +23,7 @@ tail =
[test_match_beginning.js]
[test_multi_word_search.js]
[test_queryurl.js]
[test_searchEngine.js]
[test_special_search.js]
[test_swap_protocol.js]
[test_tabmatches.js]

View File

@ -1436,6 +1436,20 @@ extends="chrome://global/content/bindings/popup.xml#popup">
type = types.join(" ");
}
// Check if we have a search engine name
let searchEngine = "";
let searchIndex = types.indexOf("search");
if (searchIndex >= 0) {
const TITLE_SEARCH_ENGINE_SEPARATOR = " \u00B7\u2013\u00B7 ";
[title, searchEngine] = title.split(TITLE_SEARCH_ENGINE_SEPARATOR);
// Remove the "search" substring so that the correct style, if any,
// is applied below.
types.splice(searchIndex, 1);
type = types.join(" ");
}
// If we have a tag match, show the tags and icon
if (type == "tag") {
// Configure the extra box for tags display
@ -1496,7 +1510,12 @@ extends="chrome://global/content/bindings/popup.xml#popup">
// Emphasize the matching search terms for the description
this._setUpDescription(this._title, title);
this._setUpDescription(this._url, url);
if (!searchEngine) {
this._setUpDescription(this._url, url);
} else {
// The search engine name, when present, is not emphasized.
this._setUpDescription(this._url, searchEngine, true);
}
// Set up overflow on a timeout because the contents of the box
// might not have a width yet even though we just changed them