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() { delayedStartupInit() {
// Asynchronously initialize the search service if necessary, to get the // Asynchronously initialize the search service if necessary, to get the
// current engine for working out the placeholder. // 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 // Delay the update for this until so that we don't change it while
// the user is looking at it / isn't expecting it. // the user is looking at it / isn't expecting it.
this._updateURLBarPlaceholder(defaultEngine.name, true); true
).then(() => {
this._searchInitComplete = true; this._searchInitComplete = true;
}); });
}, },
@ -4470,13 +4472,31 @@ const BrowserSearch = {
this._removeMaybeOfferedEngine(engineName); this._removeMaybeOfferedEngine(engineName);
break; break;
case "engine-default": case "engine-default":
if (this._searchInitComplete) { if (this._searchInitComplete && !this._usePrivateSettings) {
this._updateURLBarPlaceholder(engineName); this._updateURLBarPlaceholder(engineName, false);
}
break;
case "engine-default-private":
if (this._searchInitComplete && this._usePrivateSettings) {
this._updateURLBarPlaceholder(engineName, true);
} }
break; 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) { _addMaybeOfferedEngine(engineName) {
let selectedBrowserOffersEngine = false; let selectedBrowserOffersEngine = false;
for (let browser of gBrowser.browsers) { for (let browser of gBrowser.browsers) {
@ -4532,16 +4552,36 @@ const BrowserSearch = {
* placeholder is a string which doesn't have the engine name. * placeholder is a string which doesn't have the engine name.
*/ */
initPlaceHolder() { initPlaceHolder() {
let engineName = Services.prefs.getStringPref( const prefName =
"browser.urlbar.placeholderName", "browser.urlbar.placeholderName" +
"" (this._usePrivateSettings ? ".private" : "");
); let engineName = Services.prefs.getStringPref(prefName, "");
if (engineName) { if (engineName) {
// We can do this directly, since we know we're at DOMContentLoaded. // We can do this directly, since we know we're at DOMContentLoaded.
this._setURLBarPlaceholder(engineName); 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 * Updates the URLBar placeholder for the specified engine, delaying the
* update if required. This also saves the current engine name in preferences * update if required. This also saves the current engine name in preferences
@ -4551,24 +4591,24 @@ const BrowserSearch = {
* know they should have short names. * know they should have short names.
* *
* @param {String} engineName The search engine name to use for the update. * @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. * placeholder is not displayed.
*/ */
async _updateURLBarPlaceholder(engineName, delayUpdate = false) { async _updateURLBarPlaceholder(engineName, isPrivate, delayUpdate = false) {
if (!engineName) { if (!engineName) {
throw new Error("Expected an engineName to be specified"); throw new Error("Expected an engineName to be specified");
} }
let defaultEngines = await Services.search.getDefaultEngines(); let defaultEngines = await Services.search.getDefaultEngines();
const prefName =
"browser.urlbar.placeholderName" + (isPrivate ? ".private" : "");
if ( if (
defaultEngines.some(defaultEngine => defaultEngine.name == engineName) defaultEngines.some(defaultEngine => defaultEngine.name == engineName)
) { ) {
Services.prefs.setStringPref( Services.prefs.setStringPref(prefName, engineName);
"browser.urlbar.placeholderName",
engineName
);
} else { } 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 // Set the engine name to an empty string for non-default engines, which'll
// make sure we display the default placeholder string. // make sure we display the default placeholder string.
engineName = ""; engineName = "";
@ -4582,7 +4622,11 @@ const BrowserSearch = {
// a tab switch to a tab which has a url loaded. // a tab switch to a tab which has a url loaded.
let placeholderUpdateListener = () => { let placeholderUpdateListener = () => {
if (gURLBar.value) { 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); gURLBar.removeEventListener("input", placeholderUpdateListener);
gBrowser.tabContainer.removeEventListener( gBrowser.tabContainer.removeEventListener(
"TabSelect", "TabSelect",

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

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

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

@ -6,33 +6,36 @@
* expected URL for the engine. * expected URL for the engine.
*/ */
add_task(async function() { add_task(async function setup() {
await Services.search.addEngineWithDetails("MozSearch", { await SpecialPowers.pushPrefEnv({
set: [["browser.search.separatePrivateDefault", false]],
});
const engine = await Services.search.addEngineWithDetails("MozSearch", {
method: "GET", method: "GET",
template: "http://example.com/?q={searchTerms}", 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(); let originalEngine = await Services.search.getDefault();
await Services.search.setDefault(engine); await Services.search.setDefault(engine);
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"about:mozilla"
);
registerCleanupFunction(async function() { registerCleanupFunction(async function() {
await Services.search.setDefault(originalEngine); await Services.search.setDefault(originalEngine);
await Services.search.removeEngine(engine); await Services.search.removeEngine(engine);
try { await Services.search.removeEngine(engine2);
BrowserTestUtils.removeTab(tab);
} catch (ex) {
/* tab may have already been closed in case of failure */
}
await PlacesUtils.history.clear(); await PlacesUtils.history.clear();
}); });
});
await promiseAutocompleteResultPopup("open a search"); async function testSearch(win, expectedName, expectedBaseUrl) {
let result = await UrlbarTestUtils.getDetailsOfResultAt(window, 0); await promiseAutocompleteResultPopup("open a search", win);
let result = await UrlbarTestUtils.getDetailsOfResultAt(win, 0);
Assert.equal( Assert.equal(
result.type, result.type,
@ -42,7 +45,7 @@ add_task(async function() {
Assert.deepEqual( Assert.deepEqual(
result.searchParams, result.searchParams,
{ {
engine: "MozSearch", engine: expectedName,
keyword: undefined, keyword: undefined,
query: "open a search", query: "open a search",
suggestion: undefined, suggestion: undefined,
@ -56,14 +59,60 @@ add_task(async function() {
"Should have the search icon image" "Should have the search icon image"
); );
let tabPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); let tabPromise = BrowserTestUtils.browserLoaded(win.gBrowser.selectedBrowser);
let element = await UrlbarTestUtils.waitForAutocompleteResultAt(window, 0); let element = await UrlbarTestUtils.waitForAutocompleteResultAt(win, 0);
EventUtils.synthesizeMouseAtCenter(element, {}, window); EventUtils.synthesizeMouseAtCenter(element, {}, win);
await tabPromise; await tabPromise;
Assert.equal( Assert.equal(
gBrowser.selectedBrowser.currentURI.spec, win.gBrowser.selectedBrowser.currentURI.spec,
"http://example.com/?q=open+a+search", expectedBaseUrl + "?q=open+a+search",
"Should have loaded the correct page" "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"; "use strict";
const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml"; const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml";
const TEST_PRIVATE_ENGINE_BASENAME = "searchSuggestionEngine2.xml";
var originalEngine, extraEngine, expectedString; var originalEngine, extraEngine, extraPrivateEngine, expectedString;
var tabs = []; var tabs = [];
add_task(async function setup() { add_task(async function setup() {
@ -23,6 +24,9 @@ add_task(async function setup() {
extraEngine = await SearchTestUtils.promiseNewSearchEngine( extraEngine = await SearchTestUtils.promiseNewSearchEngine(
rootDir + TEST_ENGINE_BASENAME 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 // Force display of a tab with a URL bar, to clear out any possible placeholder
// initialization listeners that happen on startup. // initialization listeners that happen on startup.
@ -32,6 +36,10 @@ add_task(async function setup() {
); );
BrowserTestUtils.removeTab(urlTab); BrowserTestUtils.removeTab(urlTab);
await SpecialPowers.pushPrefEnv({
set: [["browser.search.separatePrivateDefault", false]],
});
registerCleanupFunction(async () => { registerCleanupFunction(async () => {
await Services.search.setDefault(originalEngine); await Services.search.setDefault(originalEngine);
for (let tab of tabs) { for (let tab of tabs) {
@ -74,7 +82,7 @@ add_task(async function test_delayed_update_placeholder() {
tabs.push(blankTab); tabs.push(blankTab);
// Pretend we've "initialized". // Pretend we've "initialized".
BrowserSearch._updateURLBarPlaceholder(extraEngine.name, true); BrowserSearch._updateURLBarPlaceholder(extraEngine.name, false, true);
Assert.equal( Assert.equal(
gURLBar.placeholder, 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. // Do it the other way to check both named engine and fallback code paths.
await BrowserTestUtils.switchTab(gBrowser, blankTab); await BrowserTestUtils.switchTab(gBrowser, blankTab);
BrowserSearch._updateURLBarPlaceholder(originalEngine.name, true); BrowserSearch._updateURLBarPlaceholder(originalEngine.name, false, true);
await TestUtils.waitForTick(); await TestUtils.waitForTick();
Assert.equal( 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. // 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(); await TestUtils.waitForTick();
Assert.equal( Assert.equal(
@ -119,3 +127,67 @@ add_task(async function test_delayed_update_placeholder() {
"Placeholder should be the default." "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 * Use this to get the current engine rather than Services.search.defaultEngine
* directly. This method makes sure that the service is first initialized. * 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. * @returns {nsISearchEngine} The current search engine.
*/ */
async currentEngine() { async currentEngine(inPrivateWindow) {
await this.ensureInitialized(); await this.ensureInitialized();
return Services.search.defaultEngine; return inPrivateWindow
? Services.search.defaultPrivateEngine
: Services.search.defaultEngine;
}, },
/** /**

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

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