зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1648468 - Part 3 - Allow UrlbarProviderTokenAliasEngines to provide its own heuristic result. r=adw
Differential Revision: https://phabricator.services.mozilla.com/D82236
This commit is contained in:
Родитель
ec02dade55
Коммит
b2ff98e2f8
|
@ -49,6 +49,7 @@ const heuristicOrder = [
|
|||
"Omnibox",
|
||||
"UnifiedComplete",
|
||||
"Autofill",
|
||||
"TokenAliasEngines",
|
||||
"HeuristicFallback",
|
||||
];
|
||||
/**
|
||||
|
|
|
@ -14,6 +14,7 @@ const { XPCOMUtils } = ChromeUtils.import(
|
|||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
|
||||
UrlbarProvider: "resource:///modules/UrlbarUtils.jsm",
|
||||
UrlbarResult: "resource:///modules/UrlbarResult.jsm",
|
||||
UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.jsm",
|
||||
|
@ -44,7 +45,7 @@ class ProviderTokenAliasEngines extends UrlbarProvider {
|
|||
* @returns {integer} one of the types from UrlbarUtils.PROVIDER_TYPE.*
|
||||
*/
|
||||
get type() {
|
||||
return UrlbarUtils.PROVIDER_TYPE.PROFILE;
|
||||
return UrlbarUtils.PROVIDER_TYPE.HEURISTIC;
|
||||
}
|
||||
|
||||
get PRIORITY() {
|
||||
|
@ -60,12 +61,34 @@ class ProviderTokenAliasEngines extends UrlbarProvider {
|
|||
* @returns {boolean} Whether this provider should be invoked for the search.
|
||||
*/
|
||||
async isActive(queryContext) {
|
||||
this._engines = [];
|
||||
if (queryContext.searchString.trim() == "@") {
|
||||
this._engines = await UrlbarSearchUtils.tokenAliasEngines();
|
||||
// Once the user starts typing a search string after the token, we hand off
|
||||
// suggestions to UrlbarProviderSearchSuggestions.
|
||||
if (
|
||||
!queryContext.searchString.startsWith("@") ||
|
||||
queryContext.tokens.length != 1
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this._engines.length;
|
||||
this._engines = await UrlbarSearchUtils.tokenAliasEngines();
|
||||
if (!this._engines.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (queryContext.searchString.trim() == "@") {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If there's no engine associated with the searchString, then we don't want
|
||||
// to block other kinds of results.
|
||||
if (UrlbarPrefs.get("autoFill") && queryContext.allowAutofill) {
|
||||
this._autofillResult = this._getAutofillResult(queryContext);
|
||||
if (this._autofillResult) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,19 +112,25 @@ class ProviderTokenAliasEngines extends UrlbarProvider {
|
|||
return;
|
||||
}
|
||||
|
||||
for (let { engine, tokenAliases } of this._engines) {
|
||||
let result = new UrlbarResult(
|
||||
UrlbarUtils.RESULT_TYPE.SEARCH,
|
||||
UrlbarUtils.RESULT_SOURCE.SEARCH,
|
||||
...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
|
||||
engine: [engine.name, UrlbarUtils.HIGHLIGHT.TYPED],
|
||||
keyword: [tokenAliases[0], UrlbarUtils.HIGHLIGHT.TYPED],
|
||||
query: ["", UrlbarUtils.HIGHLIGHT.TYPED],
|
||||
icon: engine.iconURI ? engine.iconURI.spec : null,
|
||||
keywordOffer: UrlbarUtils.KEYWORD_OFFER.SHOW,
|
||||
})
|
||||
);
|
||||
addCallback(this, result);
|
||||
if (queryContext.searchString.trim() == "@") {
|
||||
for (let { engine, tokenAliases } of this._engines) {
|
||||
let result = new UrlbarResult(
|
||||
UrlbarUtils.RESULT_TYPE.SEARCH,
|
||||
UrlbarUtils.RESULT_SOURCE.SEARCH,
|
||||
...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
|
||||
engine: [engine.name, UrlbarUtils.HIGHLIGHT.TYPED],
|
||||
keyword: [tokenAliases[0], UrlbarUtils.HIGHLIGHT.TYPED],
|
||||
query: ["", UrlbarUtils.HIGHLIGHT.TYPED],
|
||||
icon: engine.iconURI ? engine.iconURI.spec : "",
|
||||
keywordOffer: UrlbarUtils.KEYWORD_OFFER.SHOW,
|
||||
})
|
||||
);
|
||||
addCallback(this, result);
|
||||
}
|
||||
} else if (this._autofillResult) {
|
||||
addCallback(this, this._autofillResult);
|
||||
this.queries.delete(queryContext);
|
||||
return;
|
||||
}
|
||||
|
||||
this.queries.delete(queryContext);
|
||||
|
@ -121,8 +150,49 @@ class ProviderTokenAliasEngines extends UrlbarProvider {
|
|||
* @param {object} queryContext The query context object
|
||||
*/
|
||||
cancelQuery(queryContext) {
|
||||
delete this._autofillResult;
|
||||
this.queries.delete(queryContext);
|
||||
}
|
||||
|
||||
_getAutofillResult(queryContext) {
|
||||
let token = queryContext.tokens[0];
|
||||
// The user is typing a specific engine. We should show a heuristic result.
|
||||
for (let { engine, tokenAliases } of this._engines) {
|
||||
for (let alias of tokenAliases) {
|
||||
if (alias.startsWith(token.lowerCaseValue)) {
|
||||
// We found a specific engine. We will add an autofill result.
|
||||
let aliasPreservingUserCase =
|
||||
token.value + alias.substr(token.value.length);
|
||||
let value = aliasPreservingUserCase + " ";
|
||||
let result = new UrlbarResult(
|
||||
UrlbarUtils.RESULT_TYPE.SEARCH,
|
||||
UrlbarUtils.RESULT_SOURCE.SEARCH,
|
||||
...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
|
||||
engine: [engine.name, UrlbarUtils.HIGHLIGHT.TYPED],
|
||||
keyword: [aliasPreservingUserCase, UrlbarUtils.HIGHLIGHT.TYPED],
|
||||
query: ["", UrlbarUtils.HIGHLIGHT.TYPED],
|
||||
icon: engine.iconURI ? engine.iconURI.spec : "",
|
||||
keywordOffer: UrlbarUtils.KEYWORD_OFFER.HIDE,
|
||||
// For test interoperabilty with UrlbarProviderSearchSuggestions.
|
||||
suggestion: undefined,
|
||||
tailPrefix: undefined,
|
||||
tail: undefined,
|
||||
tailOffsetIndex: -1,
|
||||
isSearchHistory: false,
|
||||
})
|
||||
);
|
||||
result.heuristic = true;
|
||||
result.autofill = {
|
||||
value,
|
||||
selectionStart: queryContext.searchString.length,
|
||||
selectionEnd: value.length,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
var UrlbarProviderTokenAliasEngines = new ProviderTokenAliasEngines();
|
||||
|
|
|
@ -814,16 +814,14 @@ Search.prototype = {
|
|||
// If the heuristic result is an engine from a token alias, the search
|
||||
// restriction char, or we're in search-restriction mode, then we're done.
|
||||
// UrlbarProviderSearchSuggestions will handle suggestions, if any.
|
||||
let tokenAliasQuery =
|
||||
this._searchEngineAliasMatch &&
|
||||
this._searchEngineAliasMatch.isTokenAlias;
|
||||
let emptySearchRestriction =
|
||||
this._trimmedOriginalSearchString.length <= 3 &&
|
||||
this._leadingRestrictionToken == UrlbarTokenizer.RESTRICT.SEARCH &&
|
||||
/\s*\S?$/.test(this._trimmedOriginalSearchString);
|
||||
if (
|
||||
emptySearchRestriction ||
|
||||
tokenAliasQuery ||
|
||||
(tokenAliasEngines &&
|
||||
this._trimmedOriginalSearchString.startsWith("@")) ||
|
||||
(this.hasBehavior("search") && this.hasBehavior("restrict"))
|
||||
) {
|
||||
this._autocompleteSearch.finishSearch(true);
|
||||
|
@ -1000,60 +998,6 @@ Search.prototype = {
|
|||
return true;
|
||||
},
|
||||
|
||||
async _matchSearchEngineTokenAliasForAutofill() {
|
||||
// We need an "@engine" heuristic token.
|
||||
let token = this._heuristicToken;
|
||||
if (!token || token.length == 1 || !token.startsWith("@")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// See if any engine has a token alias that starts with the heuristic token.
|
||||
let engines = await UrlbarSearchUtils.tokenAliasEngines();
|
||||
for (let { engine, tokenAliases } of engines) {
|
||||
for (let alias of tokenAliases) {
|
||||
if (alias.startsWith(token.toLocaleLowerCase())) {
|
||||
// We found one. The match we add here is a little special compared
|
||||
// to others. It needs to be an autofill match and its `value` must
|
||||
// be the string that will be autofilled so that the controller will
|
||||
// autofill it. But it also must be a searchengine action so that the
|
||||
// front end will style it as a search engine result. The front end
|
||||
// uses `finalCompleteValue` as the URL for autofill results, so set
|
||||
// that to the moz-action URL.
|
||||
let aliasPreservingUserCase = token + alias.substr(token.length);
|
||||
let value = aliasPreservingUserCase + " ";
|
||||
this._result.setDefaultIndex(0);
|
||||
this._addMatch({
|
||||
value,
|
||||
finalCompleteValue: makeActionUrl("searchengine", {
|
||||
engineName: engine.name,
|
||||
alias: aliasPreservingUserCase,
|
||||
input: value,
|
||||
searchQuery: "",
|
||||
}),
|
||||
comment: engine.name,
|
||||
frecency: FRECENCY_DEFAULT,
|
||||
style: "autofill action searchengine",
|
||||
icon: engine.iconURI ? engine.iconURI.spec : null,
|
||||
});
|
||||
|
||||
// Set _searchEngineAliasMatch with an empty query so that we don't
|
||||
// attempt to add any more matches. When a token alias is autofilled,
|
||||
// the only match should be the one we just added.
|
||||
this._searchEngineAliasMatch = {
|
||||
engine,
|
||||
alias: aliasPreservingUserCase,
|
||||
query: "",
|
||||
isTokenAlias: true,
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
async _matchFirstHeuristicResult(conn) {
|
||||
// We always try to make the first result a special "heuristic" result. The
|
||||
// heuristics below determine what type of result it will be, if any.
|
||||
|
@ -1083,13 +1027,6 @@ Search.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
if (this.pending && shouldAutofill) {
|
||||
let matched = await this._matchSearchEngineTokenAliasForAutofill();
|
||||
if (matched) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to UrlbarProviderHeuristicFallback.
|
||||
return false;
|
||||
},
|
||||
|
|
Загрузка…
Ссылка в новой задаче