mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-23 18:26:15 +00:00
Bug 860560: make sure that defaultEngine and currentEngine stay in sync, r=gavin
--HG-- extra : rebase_source : 2a3169621b8cedf1382d738bd67072dae77cb4ce
This commit is contained in:
parent
6ca3643cbc
commit
c1fe9f539b
@ -317,6 +317,23 @@ BrowserGlue.prototype = {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case "browser-search-engine-modified":
|
||||||
|
if (data != "engine-default" && data != "engine-current") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Enforce that the search service's defaultEngine is always equal to
|
||||||
|
// its currentEngine. The search service will notify us any time either
|
||||||
|
// of them are changed (either by directly setting the relevant prefs,
|
||||||
|
// i.e. if add-ons try to change this directly, or if the
|
||||||
|
// nsIBrowserSearchService setters are called).
|
||||||
|
let ss = Services.search;
|
||||||
|
if (ss.currentEngine.name == ss.defaultEngine.name)
|
||||||
|
return;
|
||||||
|
if (data == "engine-current")
|
||||||
|
ss.defaultEngine = ss.currentEngine;
|
||||||
|
else
|
||||||
|
ss.currentEngine = ss.defaultEngine;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -351,6 +368,7 @@ BrowserGlue.prototype = {
|
|||||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||||
os.addObserver(this, "keyword-search", false);
|
os.addObserver(this, "keyword-search", false);
|
||||||
#endif
|
#endif
|
||||||
|
os.addObserver(this, "browser-search-engine-modified", false);
|
||||||
},
|
},
|
||||||
|
|
||||||
// cleanup (called on application shutdown)
|
// cleanup (called on application shutdown)
|
||||||
@ -384,6 +402,7 @@ BrowserGlue.prototype = {
|
|||||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||||
os.removeObserver(this, "keyword-search");
|
os.removeObserver(this, "keyword-search");
|
||||||
#endif
|
#endif
|
||||||
|
os.removeObserver(this, "browser-search-engine-modified");
|
||||||
},
|
},
|
||||||
|
|
||||||
_onAppDefaults: function BG__onAppDefaults() {
|
_onAppDefaults: function BG__onAppDefaults() {
|
||||||
|
@ -2670,6 +2670,15 @@ SearchService.prototype = {
|
|||||||
return this.__sortedEngines;
|
return this.__sortedEngines;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Get the original Engine object that belongs to the defaultenginename pref
|
||||||
|
// of the default branch.
|
||||||
|
get _originalDefaultEngine() {
|
||||||
|
let defaultPrefB = Services.prefs.getDefaultBranch(BROWSER_SEARCH_PREF);
|
||||||
|
let nsIPLS = Ci.nsIPrefLocalizedString;
|
||||||
|
let defaultEngine = defaultPrefB.getComplexValue("defaultenginename", nsIPLS).data;
|
||||||
|
return this.getEngineByName(defaultEngine);
|
||||||
|
},
|
||||||
|
|
||||||
_buildCache: function SRCH_SVC__buildCache() {
|
_buildCache: function SRCH_SVC__buildCache() {
|
||||||
if (!getBoolPref(BROWSER_SEARCH_PREF + "cache.enabled", true))
|
if (!getBoolPref(BROWSER_SEARCH_PREF + "cache.enabled", true))
|
||||||
return;
|
return;
|
||||||
@ -3323,6 +3332,15 @@ SearchService.prototype = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_setEngineByPref: function SRCH_SVC_setEngineByPref(aEngineType, aPref) {
|
||||||
|
this._ensureInitialized();
|
||||||
|
let newEngine = this.getEngineByName(getLocalizedPref(aPref, ""));
|
||||||
|
if (!newEngine)
|
||||||
|
FAIL("Can't find engine in store!", Cr.NS_ERROR_UNEXPECTED);
|
||||||
|
|
||||||
|
this[aEngineType] = newEngine;
|
||||||
|
},
|
||||||
|
|
||||||
// nsIBrowserSearchService
|
// nsIBrowserSearchService
|
||||||
init: function SRCH_SVC_init(observer) {
|
init: function SRCH_SVC_init(observer) {
|
||||||
LOG("SearchService.init");
|
LOG("SearchService.init");
|
||||||
@ -3620,7 +3638,10 @@ SearchService.prototype = {
|
|||||||
|
|
||||||
set defaultEngine(val) {
|
set defaultEngine(val) {
|
||||||
this._ensureInitialized();
|
this._ensureInitialized();
|
||||||
if (!(val instanceof Ci.nsISearchEngine))
|
// Sometimes we get wrapped nsISearchEngine objects (external XPCOM callers),
|
||||||
|
// and sometimes we get raw Engine JS objects (callers in this file), so
|
||||||
|
// handle both.
|
||||||
|
if (!(val instanceof Ci.nsISearchEngine) && !(val instanceof Engine))
|
||||||
FAIL("Invalid argument passed to defaultEngine setter");
|
FAIL("Invalid argument passed to defaultEngine setter");
|
||||||
|
|
||||||
let newDefaultEngine = this.getEngineByName(val.name);
|
let newDefaultEngine = this.getEngineByName(val.name);
|
||||||
@ -3632,8 +3653,22 @@ SearchService.prototype = {
|
|||||||
|
|
||||||
this._defaultEngine = newDefaultEngine;
|
this._defaultEngine = newDefaultEngine;
|
||||||
|
|
||||||
|
// Set a flag to keep track that this setter was called properly, not by
|
||||||
|
// setting the pref alone.
|
||||||
|
this._changingDefaultEngine = true;
|
||||||
let defPref = BROWSER_SEARCH_PREF + "defaultenginename";
|
let defPref = BROWSER_SEARCH_PREF + "defaultenginename";
|
||||||
setLocalizedPref(defPref, this._defaultEngine.name);
|
// If we change the default engine in the future, that change should impact
|
||||||
|
// users who have switched away from and then back to the build's "default"
|
||||||
|
// engine. So clear the user pref when the defaultEngine is set to the
|
||||||
|
// build's default engine, so that the defaultEngine getter falls back to
|
||||||
|
// whatever the default is.
|
||||||
|
if (this._defaultEngine == this._originalDefaultEngine) {
|
||||||
|
Services.prefs.clearUserPref(defPref);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setLocalizedPref(defPref, this._defaultEngine.name);
|
||||||
|
}
|
||||||
|
this._changingDefaultEngine = false;
|
||||||
|
|
||||||
notifyAction(this._defaultEngine, SEARCH_ENGINE_DEFAULT);
|
notifyAction(this._defaultEngine, SEARCH_ENGINE_DEFAULT);
|
||||||
},
|
},
|
||||||
@ -3653,7 +3688,10 @@ SearchService.prototype = {
|
|||||||
|
|
||||||
set currentEngine(val) {
|
set currentEngine(val) {
|
||||||
this._ensureInitialized();
|
this._ensureInitialized();
|
||||||
if (!(val instanceof Ci.nsISearchEngine))
|
// Sometimes we get wrapped nsISearchEngine objects (external XPCOM callers),
|
||||||
|
// and sometimes we get raw Engine JS objects (callers in this file), so
|
||||||
|
// handle both.
|
||||||
|
if (!(val instanceof Ci.nsISearchEngine) && !(val instanceof Engine))
|
||||||
FAIL("Invalid argument passed to currentEngine setter");
|
FAIL("Invalid argument passed to currentEngine setter");
|
||||||
|
|
||||||
var newCurrentEngine = this.getEngineByName(val.name);
|
var newCurrentEngine = this.getEngineByName(val.name);
|
||||||
@ -3667,12 +3705,21 @@ SearchService.prototype = {
|
|||||||
|
|
||||||
var currentEnginePref = BROWSER_SEARCH_PREF + "selectedEngine";
|
var currentEnginePref = BROWSER_SEARCH_PREF + "selectedEngine";
|
||||||
|
|
||||||
if (this._currentEngine == this.defaultEngine) {
|
// Set a flag to keep track that this setter was called properly, not by
|
||||||
|
// setting the pref alone.
|
||||||
|
this._changingCurrentEngine = true;
|
||||||
|
// If we change the default engine in the future, that change should impact
|
||||||
|
// users who have switched away from and then back to the build's "default"
|
||||||
|
// engine. So clear the user pref when the currentEngine is set to the
|
||||||
|
// build's default engine, so that the currentEngine getter falls back to
|
||||||
|
// whatever the default is.
|
||||||
|
if (this._currentEngine == this._originalDefaultEngine) {
|
||||||
Services.prefs.clearUserPref(currentEnginePref);
|
Services.prefs.clearUserPref(currentEnginePref);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setLocalizedPref(currentEnginePref, this._currentEngine.name);
|
setLocalizedPref(currentEnginePref, this._currentEngine.name);
|
||||||
}
|
}
|
||||||
|
this._changingCurrentEngine = false;
|
||||||
|
|
||||||
notifyAction(this._currentEngine, SEARCH_ENGINE_CURRENT);
|
notifyAction(this._currentEngine, SEARCH_ENGINE_CURRENT);
|
||||||
},
|
},
|
||||||
@ -3709,6 +3756,16 @@ SearchService.prototype = {
|
|||||||
}
|
}
|
||||||
engineMetadataService.flush();
|
engineMetadataService.flush();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "nsPref:changed":
|
||||||
|
let currPref = BROWSER_SEARCH_PREF + "selectedEngine";
|
||||||
|
let defPref = BROWSER_SEARCH_PREF + "defaultenginename";
|
||||||
|
if (aVerb == currPref && !this._changingCurrentEngine) {
|
||||||
|
this._setEngineByPref("currentEngine", currPref);
|
||||||
|
} else if (aVerb == defPref && !this._changingDefaultEngine) {
|
||||||
|
this._setEngineByPref("defaultEngine", defPref);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -3754,11 +3811,15 @@ SearchService.prototype = {
|
|||||||
_addObservers: function SRCH_SVC_addObservers() {
|
_addObservers: function SRCH_SVC_addObservers() {
|
||||||
Services.obs.addObserver(this, SEARCH_ENGINE_TOPIC, false);
|
Services.obs.addObserver(this, SEARCH_ENGINE_TOPIC, false);
|
||||||
Services.obs.addObserver(this, QUIT_APPLICATION_TOPIC, false);
|
Services.obs.addObserver(this, QUIT_APPLICATION_TOPIC, false);
|
||||||
|
Services.prefs.addObserver(BROWSER_SEARCH_PREF + "defaultenginename", this, false);
|
||||||
|
Services.prefs.addObserver(BROWSER_SEARCH_PREF + "selectedEngine", this, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
_removeObservers: function SRCH_SVC_removeObservers() {
|
_removeObservers: function SRCH_SVC_removeObservers() {
|
||||||
Services.obs.removeObserver(this, SEARCH_ENGINE_TOPIC);
|
Services.obs.removeObserver(this, SEARCH_ENGINE_TOPIC);
|
||||||
Services.obs.removeObserver(this, QUIT_APPLICATION_TOPIC);
|
Services.obs.removeObserver(this, QUIT_APPLICATION_TOPIC);
|
||||||
|
Services.prefs.removeObserver(BROWSER_SEARCH_PREF + "defaultenginename", this);
|
||||||
|
Services.prefs.removeObserver(BROWSER_SEARCH_PREF + "selectedEngine", this);
|
||||||
},
|
},
|
||||||
|
|
||||||
QueryInterface: function SRCH_SVC_QI(aIID) {
|
QueryInterface: function SRCH_SVC_QI(aIID) {
|
||||||
|
@ -43,29 +43,24 @@ function search_observer(aSubject, aTopic, aData) {
|
|||||||
let engine2 = search.getEngineByName("A second test engine");
|
let engine2 = search.getEngineByName("A second test engine");
|
||||||
|
|
||||||
search.defaultEngine = engine1;
|
search.defaultEngine = engine1;
|
||||||
do_check_eq(search.defaultEngine.name, "Test search engine");
|
do_check_eq(search.defaultEngine, engine1);
|
||||||
do_check_eq(search.defaultEngine.searchForm, "http://www.google.com/");
|
|
||||||
|
|
||||||
// Tests search defaultEngine when it changes
|
// Tests search defaultEngine when it changes
|
||||||
search.defaultEngine = engine2
|
search.defaultEngine = engine2
|
||||||
do_check_eq(search.defaultEngine.name, "A second test engine");
|
do_check_eq(search.defaultEngine, engine2);
|
||||||
do_check_eq(search.defaultEngine.searchForm, "https://duckduckgo.com");
|
|
||||||
|
|
||||||
// Test search defaultEngine again when we change back
|
// Test search defaultEngine again when we change back
|
||||||
search.defaultEngine = engine1;
|
search.defaultEngine = engine1;
|
||||||
do_check_eq(search.defaultEngine.name, "Test search engine");
|
do_check_eq(search.defaultEngine, engine1);
|
||||||
do_check_eq(search.defaultEngine.searchForm, "http://www.google.com/");
|
|
||||||
|
|
||||||
// Test search defaultEngine when the current default is hidden
|
// Test search defaultEngine when the current default is hidden
|
||||||
search.moveEngine(engine2, 0)
|
search.moveEngine(engine2, 0);
|
||||||
engine1.hidden = true;
|
engine1.hidden = true;
|
||||||
do_check_eq(search.defaultEngine.name, "A second test engine");
|
do_check_eq(search.defaultEngine, engine2);
|
||||||
do_check_eq(search.defaultEngine.searchForm, "https://duckduckgo.com");
|
|
||||||
|
|
||||||
// Test search defaultEngine when it is set to a hidden engine
|
// Test search defaultEngine when it is set to a hidden engine
|
||||||
search.defaultEngine = engine1;
|
search.defaultEngine = engine1;
|
||||||
do_check_eq(search.defaultEngine.name, "A second test engine");
|
do_check_eq(search.defaultEngine, engine2);
|
||||||
do_check_eq(search.defaultEngine.searchForm, "https://duckduckgo.com");
|
|
||||||
|
|
||||||
do_test_finished();
|
do_test_finished();
|
||||||
}
|
}
|
||||||
|
129
toolkit/components/search/tests/xpcshell/test_prefSync.js
Normal file
129
toolkit/components/search/tests/xpcshell/test_prefSync.js
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test that currentEngine and defaultEngine properties are updated when the
|
||||||
|
* prefs are set independently.
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||||
|
|
||||||
|
Cu.import("resource://testing-common/httpd.js");
|
||||||
|
|
||||||
|
let waitForEngines = {
|
||||||
|
"Test search engine": 1,
|
||||||
|
"A second test engine": 1
|
||||||
|
};
|
||||||
|
|
||||||
|
const PREF_BRANCH = "browser.search.";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for nsIPrefBranch::setComplexValue.
|
||||||
|
* @param aPrefName
|
||||||
|
* The name of the pref to set.
|
||||||
|
*/
|
||||||
|
function setLocalizedPref(aPrefName, aValue) {
|
||||||
|
let nsIPLS = Ci.nsIPrefLocalizedString;
|
||||||
|
let branch = Services.prefs.getBranch(PREF_BRANCH);
|
||||||
|
try {
|
||||||
|
var pls = Cc["@mozilla.org/pref-localizedstring;1"].
|
||||||
|
createInstance(Ci.nsIPrefLocalizedString);
|
||||||
|
pls.data = aValue;
|
||||||
|
branch.setComplexValue(aPrefName, nsIPLS, pls);
|
||||||
|
} catch (ex) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function search_observer(aSubject, aTopic, aData) {
|
||||||
|
let engine = aSubject.QueryInterface(Ci.nsISearchEngine);
|
||||||
|
do_print("Observer: " + aData + " for " + engine.name);
|
||||||
|
|
||||||
|
if (aData != "engine-added") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the engine is defined in `waitForEngines`, remove it from the list
|
||||||
|
if (waitForEngines[engine.name]) {
|
||||||
|
delete waitForEngines[engine.name];
|
||||||
|
} else {
|
||||||
|
// This engine is not one we're waiting for, so bail out early.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only continue when both engines have been loaded.
|
||||||
|
if (Object.keys(waitForEngines).length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let search = Services.search;
|
||||||
|
|
||||||
|
let engine1Name = "Test search engine";
|
||||||
|
let engine2Name = "A second test engine";
|
||||||
|
let engine1 = search.getEngineByName(engine1Name);
|
||||||
|
let engine2 = search.getEngineByName(engine2Name);
|
||||||
|
|
||||||
|
// Initial sanity check:
|
||||||
|
search.defaultEngine = engine1;
|
||||||
|
do_check_eq(search.defaultEngine, engine1);
|
||||||
|
search.currentEngine = engine1;
|
||||||
|
do_check_eq(search.currentEngine, engine1);
|
||||||
|
|
||||||
|
setLocalizedPref("defaultenginename", engine2Name);
|
||||||
|
// Default engine should be synced with the pref
|
||||||
|
do_check_eq(search.defaultEngine, engine2);
|
||||||
|
// Current engine should've stayed the same
|
||||||
|
do_check_eq(search.currentEngine, engine1);
|
||||||
|
|
||||||
|
setLocalizedPref("selectedEngine", engine2Name);
|
||||||
|
// Default engine should've stayed the same
|
||||||
|
do_check_eq(search.defaultEngine, engine2);
|
||||||
|
// Current engine should've been updated
|
||||||
|
do_check_eq(search.currentEngine, engine2);
|
||||||
|
|
||||||
|
// Test that setting the currentEngine to the original default engine clears
|
||||||
|
// the selectedEngine pref, rather than setting it. To do this we need to
|
||||||
|
// set the value of defaultenginename on the default branch.
|
||||||
|
let defaultBranch = Services.prefs.getDefaultBranch("");
|
||||||
|
let prefName = PREF_BRANCH + "defaultenginename";
|
||||||
|
let prefVal = "data:text/plain," + prefName + "=" + engine1Name;
|
||||||
|
defaultBranch.setCharPref(prefName, prefVal, true);
|
||||||
|
search.currentEngine = engine1;
|
||||||
|
// Current engine should've been updated
|
||||||
|
do_check_eq(search.currentEngine, engine1);
|
||||||
|
do_check_false(Services.prefs.prefHasUserValue("browser.search.selectedEngine"));
|
||||||
|
|
||||||
|
// Test that setting the defaultEngine to the original default engine clears
|
||||||
|
// the defaultenginename pref, rather than setting it.
|
||||||
|
do_check_true(Services.prefs.prefHasUserValue("browser.search.defaultenginename"));
|
||||||
|
search.defaultEngine = engine1;
|
||||||
|
do_check_eq(search.defaultEngine, engine1);
|
||||||
|
do_check_false(Services.prefs.prefHasUserValue("browser.search.defaultenginename"));
|
||||||
|
|
||||||
|
do_test_finished();
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
removeMetadata();
|
||||||
|
updateAppInfo();
|
||||||
|
|
||||||
|
let httpServer = new HttpServer();
|
||||||
|
httpServer.start(4444);
|
||||||
|
httpServer.registerDirectory("/", do_get_cwd());
|
||||||
|
|
||||||
|
do_register_cleanup(function cleanup() {
|
||||||
|
httpServer.stop(function() {});
|
||||||
|
Services.obs.removeObserver(search_observer, "browser-search-engine-modified");
|
||||||
|
});
|
||||||
|
|
||||||
|
do_test_pending();
|
||||||
|
|
||||||
|
Services.obs.addObserver(search_observer, "browser-search-engine-modified", false);
|
||||||
|
|
||||||
|
Services.search.addEngine("http://localhost:4444/data/engine.xml",
|
||||||
|
Ci.nsISearchEngine.DATA_XML,
|
||||||
|
null, false);
|
||||||
|
Services.search.addEngine("http://localhost:4444/data/engine2.xml",
|
||||||
|
Ci.nsISearchEngine.DATA_XML,
|
||||||
|
null, false);
|
||||||
|
}
|
@ -17,4 +17,5 @@ skip-if = debug && os == "linux"
|
|||||||
[test_save_sorted_engines.js]
|
[test_save_sorted_engines.js]
|
||||||
[test_purpose.js]
|
[test_purpose.js]
|
||||||
[test_engineselect.js]
|
[test_engineselect.js]
|
||||||
|
[test_prefSync.js]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user