Bug 515463 - new async autocomplete does not always respect behavior pref changes. r=mak
This happened because we were not holding a reference to our preference branch,
so it would seem to randomly stop getting notified about preference changes.
Heavily dependent on GC, and difficult to test. The fix is simple - hold a
reference to the pref branch!
--- a/suite/common/places/src/nsPlacesAutoComplete.js
+++ b/suite/common/places/src/nsPlacesAutoComplete.js
@@ -347,16 +347,19 @@ function nsPlacesAutoComplete()
"ORDER BY IFNULL(h_t.frecency, h.frecency) DESC"
);
});
//////////////////////////////////////////////////////////////////////////////
//// Initialization
// load preferences
+ this._prefs = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService).
+ getBranch(kBrowserUrlbarBranch);
this._loadPrefs(true);
// register observers
this._os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
this._os.addObserver(this, kQuitApplication, false);
}
@@ -493,21 +496,18 @@ nsPlacesAutoComplete.prototype = {
//// nsIObserver
observe: function PAC_observe(aSubject, aTopic, aData)
{
if (aTopic == kQuitApplication) {
this._os.removeObserver(this, kQuitApplication);
// Remove our preference observer.
- let prefs = Cc["@mozilla.org/preferences-service;1"].
- getService(Ci.nsIPrefService).
- getBranch(kBrowserUrlbarBranch).
- QueryInterface(Ci.nsIPrefBranch2);
- prefs.removeObserver("", this);
+ this._prefs.removeObserver("", this);
+ delete this._prefs;
// Finalize the statements that we have used.
let stmts = [
"_defaultQuery",
"_historyQuery",
"_bookmarkQuery",
"_tagsQuery",
"_typedQuery",
@@ -638,32 +638,30 @@ nsPlacesAutoComplete.prototype = {
* Loads the preferences that we care about.
*
* @param [optional] aRegisterObserver
* Indicates if the preference observer should be added or not. The
* default value is false.
*/
_loadPrefs: function PAC_loadPrefs(aRegisterObserver)
{
- let prefs = Cc["@mozilla.org/preferences-service;1"].
- getService(Ci.nsIPrefService).
- getBranch(kBrowserUrlbarBranch);
+ let self = this;
function safeGetter(aName, aDefault) {
let types = {
boolean: "Bool",
number: "Int",
string: "Char"
};
let type = types[typeof(aDefault)];
if (!type)
throw "Unknown type!";
// If the pref isn't set, we want to use the default.
try {
- return prefs["get" + type + "Pref"](aName);
+ return self._prefs["get" + type + "Pref"](aName);
}
catch (e) {
return aDefault;
}
}
this._enabled = safeGetter("autocomplete.enabled", true);
this._matchBehavior = safeGetter("matchBehavior", MATCH_BOUNDARY_ANYWHERE);
@@ -684,17 +682,17 @@ nsPlacesAutoComplete.prototype = {
// Validate matchBehavior; default to MATCH_BOUNDARY_ANYWHERE.
if (this._matchBehavior != MATCH_ANYWHERE &&
this._matchBehavior != MATCH_BOUNDARY &&
this._matchBehavior != MATCH_BEGINNING)
this._matchBehavior = MATCH_BOUNDARY_ANYWHERE;
// register observer
if (aRegisterObserver) {
- let pb = prefs.QueryInterface(Ci.nsIPrefBranch2);
+ let pb = this._prefs.QueryInterface(Ci.nsIPrefBranch2);
pb.addObserver("", this, false);
}
},
/**
* Given an array of tokens, this function determines which query should be
* ran. It also removes any special search tokens.
*