зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1594622
- Quantumbar: Remove the context.preselected property and rely on result.heuristic instead r=mak
Please see bug 1594622
for a description.
Differential Revision: https://phabricator.services.mozilla.com/D52120
--HG--
extra : moz-landing-system : lando
This commit is contained in:
Родитель
da04815436
Коммит
2687f37446
|
@ -82,7 +82,6 @@ add_task(async function tip_onResultPicked_mainButton_noURL_enter() {
|
||||||
waitForFocus,
|
waitForFocus,
|
||||||
value: "test",
|
value: "test",
|
||||||
});
|
});
|
||||||
EventUtils.synthesizeKey("KEY_ArrowDown");
|
|
||||||
EventUtils.synthesizeKey("KEY_Enter");
|
EventUtils.synthesizeKey("KEY_Enter");
|
||||||
await ext.awaitMessage("onResultPicked received");
|
await ext.awaitMessage("onResultPicked received");
|
||||||
await ext.unload();
|
await ext.unload();
|
||||||
|
@ -121,7 +120,6 @@ add_task(async function tip_onResultPicked_mainButton_url_enter() {
|
||||||
ext.onMessage("onResultPicked received", () => {
|
ext.onMessage("onResultPicked received", () => {
|
||||||
Assert.ok(false, "onResultPicked should not be called");
|
Assert.ok(false, "onResultPicked should not be called");
|
||||||
});
|
});
|
||||||
EventUtils.synthesizeKey("KEY_ArrowDown");
|
|
||||||
EventUtils.synthesizeKey("KEY_Enter");
|
EventUtils.synthesizeKey("KEY_Enter");
|
||||||
await loadedPromise;
|
await loadedPromise;
|
||||||
Assert.equal(gBrowser.currentURI.spec, "http://example.com/");
|
Assert.equal(gBrowser.currentURI.spec, "http://example.com/");
|
||||||
|
@ -171,7 +169,7 @@ add_task(async function tip_onResultPicked_helpButton_url_enter() {
|
||||||
ext.onMessage("onResultPicked received", () => {
|
ext.onMessage("onResultPicked received", () => {
|
||||||
Assert.ok(false, "onResultPicked should not be called");
|
Assert.ok(false, "onResultPicked should not be called");
|
||||||
});
|
});
|
||||||
EventUtils.synthesizeKey("KEY_ArrowDown", { repeat: 2 });
|
EventUtils.synthesizeKey("KEY_ArrowDown");
|
||||||
EventUtils.synthesizeKey("KEY_Enter");
|
EventUtils.synthesizeKey("KEY_Enter");
|
||||||
await loadedPromise;
|
await loadedPromise;
|
||||||
Assert.equal(gBrowser.currentURI.spec, "http://example.com/");
|
Assert.equal(gBrowser.currentURI.spec, "http://example.com/");
|
||||||
|
|
|
@ -820,6 +820,129 @@ add_task(async function test_activeInactiveAndRestrictingProviders() {
|
||||||
await ext.unload();
|
await ext.unload();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Adds a restricting provider that returns a heuristic result. The actual
|
||||||
|
// result created from the extension's result should be a heuristic.
|
||||||
|
add_task(async function test_heuristicRestricting() {
|
||||||
|
let ext = ExtensionTestUtils.loadExtension({
|
||||||
|
manifest: {
|
||||||
|
permissions: ["urlbar"],
|
||||||
|
},
|
||||||
|
isPrivileged: true,
|
||||||
|
incognitoOverride: "spanning",
|
||||||
|
background() {
|
||||||
|
browser.urlbar.onBehaviorRequested.addListener(query => {
|
||||||
|
return "restricting";
|
||||||
|
}, "test");
|
||||||
|
browser.urlbar.onResultsRequested.addListener(query => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: "url",
|
||||||
|
source: "history",
|
||||||
|
heuristic: true,
|
||||||
|
payload: {
|
||||||
|
title: "Test result",
|
||||||
|
url: "http://example.com/",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}, "test");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await ext.startup();
|
||||||
|
|
||||||
|
// Check the provider.
|
||||||
|
let provider = UrlbarProvidersManager.getProvider("test");
|
||||||
|
Assert.ok(provider);
|
||||||
|
|
||||||
|
// Run a query.
|
||||||
|
let context = new UrlbarQueryContext({
|
||||||
|
allowAutofill: false,
|
||||||
|
isPrivate: false,
|
||||||
|
maxResults: 10,
|
||||||
|
searchString: "test",
|
||||||
|
});
|
||||||
|
let controller = new UrlbarController({
|
||||||
|
browserWindow: {
|
||||||
|
location: {
|
||||||
|
href: AppConstants.BROWSER_CHROME_URL,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await controller.startQuery(context);
|
||||||
|
|
||||||
|
// Check the results.
|
||||||
|
Assert.equal(context.results.length, 1);
|
||||||
|
Assert.ok(context.results[0].heuristic);
|
||||||
|
|
||||||
|
await ext.unload();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Adds a non-restricting provider that returns a heuristic result. The actual
|
||||||
|
// result created from the extension's result should *not* be a heuristic, and
|
||||||
|
// the usual UnifiedComplete heuristic should be present.
|
||||||
|
add_task(async function test_heuristicNonRestricting() {
|
||||||
|
let ext = ExtensionTestUtils.loadExtension({
|
||||||
|
manifest: {
|
||||||
|
permissions: ["urlbar"],
|
||||||
|
},
|
||||||
|
isPrivileged: true,
|
||||||
|
incognitoOverride: "spanning",
|
||||||
|
background() {
|
||||||
|
browser.urlbar.onBehaviorRequested.addListener(query => {
|
||||||
|
return "active";
|
||||||
|
}, "test");
|
||||||
|
browser.urlbar.onResultsRequested.addListener(query => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: "url",
|
||||||
|
source: "history",
|
||||||
|
heuristic: true,
|
||||||
|
payload: {
|
||||||
|
title: "Test result",
|
||||||
|
url: "http://example.com/",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}, "test");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await ext.startup();
|
||||||
|
|
||||||
|
// Check the provider.
|
||||||
|
let provider = UrlbarProvidersManager.getProvider("test");
|
||||||
|
Assert.ok(provider);
|
||||||
|
|
||||||
|
// Run a query.
|
||||||
|
let context = new UrlbarQueryContext({
|
||||||
|
allowAutofill: false,
|
||||||
|
isPrivate: false,
|
||||||
|
maxResults: 10,
|
||||||
|
searchString: "test",
|
||||||
|
});
|
||||||
|
let controller = new UrlbarController({
|
||||||
|
browserWindow: {
|
||||||
|
location: {
|
||||||
|
href: AppConstants.BROWSER_CHROME_URL,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await controller.startQuery(context);
|
||||||
|
|
||||||
|
// Check the results. The first result should be UnifiedComplete's heuristic.
|
||||||
|
let firstResult = context.results[0];
|
||||||
|
Assert.ok(firstResult.heuristic);
|
||||||
|
Assert.equal(firstResult.type, UrlbarUtils.RESULT_TYPE.SEARCH);
|
||||||
|
Assert.equal(firstResult.source, UrlbarUtils.RESULT_SOURCE.SEARCH);
|
||||||
|
Assert.equal(firstResult.payload.engine, "Test engine");
|
||||||
|
|
||||||
|
// The extension result should be present but not the heuristic.
|
||||||
|
let result = context.results.find(r => r.title == "Test result");
|
||||||
|
Assert.ok(result);
|
||||||
|
Assert.ok(!result.heuristic);
|
||||||
|
|
||||||
|
await ext.unload();
|
||||||
|
});
|
||||||
|
|
||||||
// Adds an active provider that doesn't have a listener for onResultsRequested.
|
// Adds an active provider that doesn't have a listener for onResultsRequested.
|
||||||
// No results should be added.
|
// No results should be added.
|
||||||
add_task(async function test_onResultsRequestedNotImplemented() {
|
add_task(async function test_onResultsRequestedNotImplemented() {
|
||||||
|
|
|
@ -404,7 +404,7 @@ class UrlbarController {
|
||||||
case "resultsadded": {
|
case "resultsadded": {
|
||||||
// We should connect to an heuristic result, if it exists.
|
// We should connect to an heuristic result, if it exists.
|
||||||
if (
|
if (
|
||||||
(result == context.results[0] && context.preselected) ||
|
(result == context.results[0] && result.heuristic) ||
|
||||||
result.autofill
|
result.autofill
|
||||||
) {
|
) {
|
||||||
if (result.type == UrlbarUtils.RESULT_TYPE.SEARCH) {
|
if (result.type == UrlbarUtils.RESULT_TYPE.SEARCH) {
|
||||||
|
|
|
@ -75,13 +75,11 @@ class MuxerUnifiedComplete extends UrlbarMuxer {
|
||||||
if (!context.results.length) {
|
if (!context.results.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Look for an heuristic result. If it's a preselected search result, use
|
// Look for an heuristic result. If it's a search result, use search
|
||||||
// search buckets, otherwise use normal buckets.
|
// buckets, otherwise use normal buckets.
|
||||||
let heuristicResult = context.results.find(r => r.heuristic);
|
let heuristicResult = context.results.find(r => r.heuristic);
|
||||||
let buckets =
|
let buckets =
|
||||||
context.preselected &&
|
heuristicResult && heuristicResult.type == UrlbarUtils.RESULT_TYPE.SEARCH
|
||||||
heuristicResult &&
|
|
||||||
heuristicResult.type == UrlbarUtils.RESULT_TYPE.SEARCH
|
|
||||||
? UrlbarPrefs.get("matchBucketsSearch")
|
? UrlbarPrefs.get("matchBucketsSearch")
|
||||||
: UrlbarPrefs.get("matchBuckets");
|
: UrlbarPrefs.get("matchBuckets");
|
||||||
logger.debug(`Buckets: ${buckets}`);
|
logger.debug(`Buckets: ${buckets}`);
|
||||||
|
@ -108,8 +106,7 @@ class MuxerUnifiedComplete extends UrlbarMuxer {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
group == UrlbarUtils.RESULT_GROUP.HEURISTIC &&
|
group == UrlbarUtils.RESULT_GROUP.HEURISTIC &&
|
||||||
result == heuristicResult &&
|
result == heuristicResult
|
||||||
context.preselected
|
|
||||||
) {
|
) {
|
||||||
// Handle the heuristic result.
|
// Handle the heuristic result.
|
||||||
sortedResults.unshift(result);
|
sortedResults.unshift(result);
|
||||||
|
|
|
@ -318,6 +318,13 @@ class UrlbarProviderExtension extends UrlbarProvider {
|
||||||
extResult.payload || {}
|
extResult.payload || {}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
if (extResult.heuristic && this.behavior == "restricting") {
|
||||||
|
// The muxer chooses the final heuristic result by taking the first one
|
||||||
|
// that claims to be the heuristic. We don't want extensions to clobber
|
||||||
|
// UnifiedComplete's heuristic, so we allow this only if the provider is
|
||||||
|
// restricting.
|
||||||
|
result.heuristic = extResult.heuristic;
|
||||||
|
}
|
||||||
if (extResult.suggestedIndex !== undefined) {
|
if (extResult.suggestedIndex !== undefined) {
|
||||||
result.suggestedIndex = extResult.suggestedIndex;
|
result.suggestedIndex = extResult.suggestedIndex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,28 +218,24 @@ function convertResultToMatches(context, result, urls) {
|
||||||
if (!match) {
|
if (!match) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Manage autofill and preselected properties for the first match.
|
// Manage autofill for the first match.
|
||||||
if (isHeuristic) {
|
if (isHeuristic && style.includes("autofill") && result.defaultIndex == 0) {
|
||||||
if (style.includes("autofill") && result.defaultIndex == 0) {
|
let autofillValue = result.getValueAt(i);
|
||||||
let autofillValue = result.getValueAt(i);
|
if (
|
||||||
if (
|
autofillValue
|
||||||
autofillValue
|
.toLocaleLowerCase()
|
||||||
.toLocaleLowerCase()
|
.startsWith(context.searchString.toLocaleLowerCase())
|
||||||
.startsWith(context.searchString.toLocaleLowerCase())
|
) {
|
||||||
) {
|
match.autofill = {
|
||||||
match.autofill = {
|
value:
|
||||||
value:
|
context.searchString +
|
||||||
context.searchString +
|
autofillValue.substring(context.searchString.length),
|
||||||
autofillValue.substring(context.searchString.length),
|
selectionStart: context.searchString.length,
|
||||||
selectionStart: context.searchString.length,
|
selectionEnd: autofillValue.length,
|
||||||
selectionEnd: autofillValue.length,
|
};
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context.preselected = true;
|
|
||||||
match.heuristic = true;
|
|
||||||
}
|
}
|
||||||
|
match.heuristic = isHeuristic;
|
||||||
matches.push(match);
|
matches.push(match);
|
||||||
}
|
}
|
||||||
return { matches, done };
|
return { matches, done };
|
||||||
|
|
|
@ -442,10 +442,12 @@ class UrlbarView {
|
||||||
}
|
}
|
||||||
this._updateResults(queryContext);
|
this._updateResults(queryContext);
|
||||||
|
|
||||||
let isFirstPreselectedResult = false;
|
let isHeuristicResult = false;
|
||||||
if (queryContext.lastResultCount == 0) {
|
if (queryContext.lastResultCount == 0) {
|
||||||
if (queryContext.preselected) {
|
let firstResult = queryContext.results[0];
|
||||||
isFirstPreselectedResult = true;
|
|
||||||
|
if (firstResult.heuristic) {
|
||||||
|
isHeuristicResult = true;
|
||||||
this._selectElement(this._getFirstSelectableElement(), {
|
this._selectElement(this._getFirstSelectableElement(), {
|
||||||
updateInput: false,
|
updateInput: false,
|
||||||
setAccessibleFocus: this.controller._userSelectionBehavior == "arrow",
|
setAccessibleFocus: this.controller._userSelectionBehavior == "arrow",
|
||||||
|
@ -469,15 +471,15 @@ class UrlbarView {
|
||||||
|
|
||||||
// The input field applies autofill on input, without waiting for results.
|
// The input field applies autofill on input, without waiting for results.
|
||||||
// Once we get results, we can ask it to correct wrong predictions.
|
// Once we get results, we can ask it to correct wrong predictions.
|
||||||
this.input.maybeClearAutofillPlaceholder(queryContext.results[0]);
|
this.input.maybeClearAutofillPlaceholder(firstResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._openPanel();
|
this._openPanel();
|
||||||
|
|
||||||
if (isFirstPreselectedResult) {
|
if (isHeuristicResult) {
|
||||||
// The first, preselected result may be a search alias result, so apply
|
// The heuristic result may be a search alias result, so apply formatting
|
||||||
// formatting if necessary. Conversely, the first result of the previous
|
// if necessary. Conversely, the heuristic result of the previous query
|
||||||
// query may have been an alias, so remove formatting if necessary.
|
// may have been an alias, so remove formatting if necessary.
|
||||||
this.input.formatValue();
|
this.input.formatValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@ It is augmented as it progresses through the system, with various information:
|
||||||
// RESULT_SOURCE.*, that can be returned by the model.
|
// RESULT_SOURCE.*, that can be returned by the model.
|
||||||
|
|
||||||
// Properties added by the Model.
|
// Properties added by the Model.
|
||||||
preselected; // {boolean} whether the first result should be preselected.
|
|
||||||
results; // {array} list of UrlbarResult objects.
|
results; // {array} list of UrlbarResult objects.
|
||||||
tokens; // {array} tokens extracted from the searchString, each token is an
|
tokens; // {array} tokens extracted from the searchString, each token is an
|
||||||
// object in the form {type, value, lowerCaseValue}.
|
// object in the form {type, value, lowerCaseValue}.
|
||||||
|
|
|
@ -115,7 +115,6 @@ add_task(async function test_preselectedHeuristic_singleProvider() {
|
||||||
let providerName = registerBasicTestProvider(matches);
|
let providerName = registerBasicTestProvider(matches);
|
||||||
let context = createContext(undefined, {
|
let context = createContext(undefined, {
|
||||||
providers: [providerName],
|
providers: [providerName],
|
||||||
preselected: true,
|
|
||||||
});
|
});
|
||||||
let controller = new UrlbarController({
|
let controller = new UrlbarController({
|
||||||
browserWindow: {
|
browserWindow: {
|
||||||
|
@ -173,7 +172,6 @@ add_task(async function test_preselectedHeuristic_multiProviders() {
|
||||||
|
|
||||||
let context = createContext(undefined, {
|
let context = createContext(undefined, {
|
||||||
providers: [provider1Name, provider2Name],
|
providers: [provider1Name, provider2Name],
|
||||||
preselected: true,
|
|
||||||
});
|
});
|
||||||
let controller = new UrlbarController({
|
let controller = new UrlbarController({
|
||||||
browserWindow: {
|
browserWindow: {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче