Bug 1562926 - Use the default private search engine in the address bar. r=daleharvey

Differential Revision: https://phabricator.services.mozilla.com/D43244

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Mark Banner 2019-08-29 14:43:43 +00:00
Родитель fb6609d49c
Коммит 4256dfcab4
6 изменённых файлов: 219 добавлений и 45 удалений

Просмотреть файл

@ -4435,10 +4435,12 @@ const BrowserSearch = {
delayedStartupInit() {
// Asynchronously initialize the search service if necessary, to get the
// current engine for working out the placeholder.
Services.search.getDefault().then(defaultEngine => {
this._updateURLBarPlaceholderFromDefaultEngine(
this._usePrivateSettings,
// Delay the update for this until so that we don't change it while
// the user is looking at it / isn't expecting it.
this._updateURLBarPlaceholder(defaultEngine.name, true);
true
).then(() => {
this._searchInitComplete = true;
});
},
@ -4470,13 +4472,31 @@ const BrowserSearch = {
this._removeMaybeOfferedEngine(engineName);
break;
case "engine-default":
if (this._searchInitComplete) {
this._updateURLBarPlaceholder(engineName);
if (this._searchInitComplete && !this._usePrivateSettings) {
this._updateURLBarPlaceholder(engineName, false);
}
break;
case "engine-default-private":
if (this._searchInitComplete && this._usePrivateSettings) {
this._updateURLBarPlaceholder(engineName, true);
}
break;
}
},
/**
* @returns True if we are using a separate default private engine, and
* we are in a private window.
*/
get _usePrivateSettings() {
return (
Services.prefs.getBoolPref(
"browser.search.separatePrivateDefault",
true
) && PrivateBrowsingUtils.isWindowPrivate(window)
);
},
_addMaybeOfferedEngine(engineName) {
let selectedBrowserOffersEngine = false;
for (let browser of gBrowser.browsers) {
@ -4532,16 +4552,36 @@ const BrowserSearch = {
* placeholder is a string which doesn't have the engine name.
*/
initPlaceHolder() {
let engineName = Services.prefs.getStringPref(
"browser.urlbar.placeholderName",
""
);
const prefName =
"browser.urlbar.placeholderName" +
(this._usePrivateSettings ? ".private" : "");
let engineName = Services.prefs.getStringPref(prefName, "");
if (engineName) {
// We can do this directly, since we know we're at DOMContentLoaded.
this._setURLBarPlaceholder(engineName);
}
},
/**
* This is a wrapper around '_updateURLBarPlaceholder' that uses the
* appropraite default engine to get the engine name.
*
* @param {Boolean} isPrivate Set to true if this is a private window.
* @param {Boolean} [delayUpdate] Set to true, to delay update until the
* placeholder is not displayed.
*/
async _updateURLBarPlaceholderFromDefaultEngine(
isPrivate,
delayUpdate = false
) {
const getDefault = isPrivate
? Services.search.getDefaultPrivate
: Services.search.getDefault;
let defaultEngine = await getDefault();
this._updateURLBarPlaceholder(defaultEngine.name, isPrivate, delayUpdate);
},
/**
* Updates the URLBar placeholder for the specified engine, delaying the
* update if required. This also saves the current engine name in preferences
@ -4551,24 +4591,24 @@ const BrowserSearch = {
* know they should have short names.
*
* @param {String} engineName The search engine name to use for the update.
* @param {Boolean} delayUpdate Set to true, to delay update until the
* @param {Boolean} isPrivate Set to true if this is a private window.
* @param {Boolean} [delayUpdate] Set to true, to delay update until the
* placeholder is not displayed.
*/
async _updateURLBarPlaceholder(engineName, delayUpdate = false) {
async _updateURLBarPlaceholder(engineName, isPrivate, delayUpdate = false) {
if (!engineName) {
throw new Error("Expected an engineName to be specified");
}
let defaultEngines = await Services.search.getDefaultEngines();
const prefName =
"browser.urlbar.placeholderName" + (isPrivate ? ".private" : "");
if (
defaultEngines.some(defaultEngine => defaultEngine.name == engineName)
) {
Services.prefs.setStringPref(
"browser.urlbar.placeholderName",
engineName
);
Services.prefs.setStringPref(prefName, engineName);
} else {
Services.prefs.clearUserPref("browser.urlbar.placeholderName");
Services.prefs.clearUserPref(prefName);
// Set the engine name to an empty string for non-default engines, which'll
// make sure we display the default placeholder string.
engineName = "";
@ -4582,7 +4622,11 @@ const BrowserSearch = {
// a tab switch to a tab which has a url loaded.
let placeholderUpdateListener = () => {
if (gURLBar.value) {
this._setURLBarPlaceholder(engineName);
// By the time the user has switched, they may have changed the engine
// again, so we need to call this function again but with the
// new engine name.
// No need to await for this to finish, we're in a listener here anyway.
this._updateURLBarPlaceholderFromDefaultEngine(isPrivate, false);
gURLBar.removeEventListener("input", placeholderUpdateListener);
gBrowser.tabContainer.removeEventListener(
"TabSelect",

Просмотреть файл

@ -176,6 +176,7 @@ support-files =
[browser_urlbarPlaceholder.js]
support-files =
searchSuggestionEngine.xml
searchSuggestionEngine2.xml
searchSuggestionEngine.sjs
[browser_urlbarRevert.js]
[browser_urlbarSearchFunction.js]

Просмотреть файл

@ -6,33 +6,36 @@
* expected URL for the engine.
*/
add_task(async function() {
await Services.search.addEngineWithDetails("MozSearch", {
add_task(async function setup() {
await SpecialPowers.pushPrefEnv({
set: [["browser.search.separatePrivateDefault", false]],
});
const engine = await Services.search.addEngineWithDetails("MozSearch", {
method: "GET",
template: "http://example.com/?q={searchTerms}",
});
let engine = Services.search.getEngineByName("MozSearch");
const engine2 = await Services.search.addEngineWithDetails(
"MozSearchPrivate",
{
method: "GET",
template: "http://example.com/private?q={searchTerms}",
}
);
let originalEngine = await Services.search.getDefault();
await Services.search.setDefault(engine);
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"about:mozilla"
);
registerCleanupFunction(async function() {
await Services.search.setDefault(originalEngine);
await Services.search.removeEngine(engine);
try {
BrowserTestUtils.removeTab(tab);
} catch (ex) {
/* tab may have already been closed in case of failure */
}
await Services.search.removeEngine(engine2);
await PlacesUtils.history.clear();
});
});
await promiseAutocompleteResultPopup("open a search");
let result = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
async function testSearch(win, expectedName, expectedBaseUrl) {
await promiseAutocompleteResultPopup("open a search", win);
let result = await UrlbarTestUtils.getDetailsOfResultAt(win, 0);
Assert.equal(
result.type,
@ -42,7 +45,7 @@ add_task(async function() {
Assert.deepEqual(
result.searchParams,
{
engine: "MozSearch",
engine: expectedName,
keyword: undefined,
query: "open a search",
suggestion: undefined,
@ -56,14 +59,60 @@ add_task(async function() {
"Should have the search icon image"
);
let tabPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
let element = await UrlbarTestUtils.waitForAutocompleteResultAt(window, 0);
EventUtils.synthesizeMouseAtCenter(element, {}, window);
let tabPromise = BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
let element = await UrlbarTestUtils.waitForAutocompleteResultAt(win, 0);
EventUtils.synthesizeMouseAtCenter(element, {}, win);
await tabPromise;
Assert.equal(
gBrowser.selectedBrowser.currentURI.spec,
"http://example.com/?q=open+a+search",
win.gBrowser.selectedBrowser.currentURI.spec,
expectedBaseUrl + "?q=open+a+search",
"Should have loaded the correct page"
);
}
add_task(async function test_search_normal_window() {
const tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"about:mozilla"
);
registerCleanupFunction(async function() {
try {
BrowserTestUtils.removeTab(tab);
} catch (ex) {
/* tab may have already been closed in case of failure */
}
});
await testSearch(window, "MozSearch", "http://example.com/");
});
add_task(async function test_search_private_window_no_separate_default() {
const win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
registerCleanupFunction(async function() {
await BrowserTestUtils.closeWindow(win);
});
await testSearch(win, "MozSearch", "http://example.com/");
});
add_task(async function test_search_private_window() {
await SpecialPowers.pushPrefEnv({
set: [["browser.search.separatePrivateDefault", true]],
});
let engine = Services.search.getEngineByName("MozSearchPrivate");
let originalEngine = await Services.search.getDefaultPrivate();
await Services.search.setDefaultPrivate(engine);
registerCleanupFunction(async () => {
await BrowserTestUtils.closeWindow(win);
await Services.search.setDefaultPrivate(originalEngine);
});
const win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
await testSearch(win, "MozSearchPrivate", "http://example.com/private");
});

Просмотреть файл

@ -9,8 +9,9 @@
"use strict";
const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";
const TEST_PRIVATE_ENGINE_BASENAME = "searchSuggestionEngine2.xml";
var originalEngine, extraEngine, expectedString;
var originalEngine, extraEngine, extraPrivateEngine, expectedString;
var tabs = [];
add_task(async function setup() {
@ -23,6 +24,9 @@ add_task(async function setup() {
extraEngine = await SearchTestUtils.promiseNewSearchEngine(
rootDir + TEST_ENGINE_BASENAME
);
extraPrivateEngine = await SearchTestUtils.promiseNewSearchEngine(
rootDir + TEST_PRIVATE_ENGINE_BASENAME
);
// Force display of a tab with a URL bar, to clear out any possible placeholder
// initialization listeners that happen on startup.
@ -32,6 +36,10 @@ add_task(async function setup() {
);
BrowserTestUtils.removeTab(urlTab);
await SpecialPowers.pushPrefEnv({
set: [["browser.search.separatePrivateDefault", false]],
});
registerCleanupFunction(async () => {
await Services.search.setDefault(originalEngine);
for (let tab of tabs) {
@ -74,7 +82,7 @@ add_task(async function test_delayed_update_placeholder() {
tabs.push(blankTab);
// Pretend we've "initialized".
BrowserSearch._updateURLBarPlaceholder(extraEngine.name, true);
BrowserSearch._updateURLBarPlaceholder(extraEngine.name, false, true);
Assert.equal(
gURLBar.placeholder,
@ -93,7 +101,7 @@ add_task(async function test_delayed_update_placeholder() {
// Do it the other way to check both named engine and fallback code paths.
await BrowserTestUtils.switchTab(gBrowser, blankTab);
BrowserSearch._updateURLBarPlaceholder(originalEngine.name, true);
BrowserSearch._updateURLBarPlaceholder(originalEngine.name, false, true);
await TestUtils.waitForTick();
Assert.equal(
@ -110,7 +118,7 @@ add_task(async function test_delayed_update_placeholder() {
);
// Now check when we have a URL displayed, the placeholder is updated straight away.
BrowserSearch._updateURLBarPlaceholder(extraEngine.name);
BrowserSearch._updateURLBarPlaceholder(extraEngine.name, false);
await TestUtils.waitForTick();
Assert.equal(
@ -119,3 +127,67 @@ add_task(async function test_delayed_update_placeholder() {
"Placeholder should be the default."
);
});
add_task(async function test_private_window_no_separate_engine() {
const win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
await Services.search.setDefault(extraEngine);
await TestUtils.waitForCondition(
() =>
win.gURLBar.placeholder == win.gURLBar.getAttribute("defaultPlaceholder"),
"The placeholder should match the default placeholder for non-built-in engines."
);
Assert.equal(
win.gURLBar.placeholder,
win.gURLBar.getAttribute("defaultPlaceholder")
);
await Services.search.setDefault(originalEngine);
await TestUtils.waitForCondition(
() => win.gURLBar.placeholder == expectedString,
"The placeholder should include the engine name for built-in engines."
);
Assert.equal(win.gURLBar.placeholder, expectedString);
await BrowserTestUtils.closeWindow(win);
});
add_task(async function test_private_window_separate_engine() {
await SpecialPowers.pushPrefEnv({
set: [["browser.search.separatePrivateDefault", true]],
});
const originalPrivateEngine = await Services.search.getDefaultPrivate();
registerCleanupFunction(async () => {
await Services.search.setDefaultPrivate(originalPrivateEngine);
});
const win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
// Keep the normal default as a different string to the private, so that we
// can be sure we're testing the right thing.
await Services.search.setDefault(originalEngine);
await Services.search.setDefaultPrivate(extraPrivateEngine);
await TestUtils.waitForCondition(
() =>
win.gURLBar.placeholder == win.gURLBar.getAttribute("defaultPlaceholder"),
"The placeholder should match the default placeholder for non-built-in engines."
);
Assert.equal(
win.gURLBar.placeholder,
win.gURLBar.getAttribute("defaultPlaceholder")
);
await Services.search.setDefault(extraEngine);
await Services.search.setDefaultPrivate(originalEngine);
await TestUtils.waitForCondition(
() => win.gURLBar.placeholder == expectedString,
"The placeholder should include the engine name for built-in engines."
);
Assert.equal(win.gURLBar.placeholder, expectedString);
await BrowserTestUtils.closeWindow(win);
});

Просмотреть файл

@ -273,12 +273,16 @@ var PlacesSearchAutocompleteProvider = Object.freeze({
* Use this to get the current engine rather than Services.search.defaultEngine
* directly. This method makes sure that the service is first initialized.
*
* @param {boolean} inPrivateWindow
* Set to true if this search is being run in a private window.
* @returns {nsISearchEngine} The current search engine.
*/
async currentEngine() {
async currentEngine(inPrivateWindow) {
await this.ensureInitialized();
return Services.search.defaultEngine;
return inPrivateWindow
? Services.search.defaultPrivateEngine
: Services.search.defaultEngine;
},
/**

Просмотреть файл

@ -1033,7 +1033,9 @@ Search.prototype = {
if (this._searchEngineAliasMatch) {
engine = this._searchEngineAliasMatch.engine;
} else {
engine = await PlacesSearchAutocompleteProvider.currentEngine();
engine = await PlacesSearchAutocompleteProvider.currentEngine(
this._inPrivateWindow
);
if (!this.pending) {
return;
}
@ -1727,7 +1729,9 @@ Search.prototype = {
},
async _matchCurrentSearchEngine() {
let engine = await PlacesSearchAutocompleteProvider.currentEngine();
let engine = await PlacesSearchAutocompleteProvider.currentEngine(
this._inPrivateWindow
);
if (!engine || !this.pending) {
return false;
}