mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-06 21:05:37 +00:00
Bug 1254194: Add XPCOMUtils.defineLazyPreferenceGetter. r=billm
MozReview-Commit-ID: JBVelZ0Xg2H --HG-- extra : rebase_source : 3909e75aa6b24ed2a1d2663c11be69c27f4de1e7
This commit is contained in:
parent
c7733098d7
commit
bd8adfebce
@ -283,6 +283,63 @@ this.XPCOMUtils = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Defines a getter on a specified object for preference value. The
|
||||
* preference is read the first time that the property is accessed,
|
||||
* and is thereafter kept up-to-date using a preference observer.
|
||||
*
|
||||
* @param aObject
|
||||
* The object to define the lazy getter on.
|
||||
* @param aName
|
||||
* The name of the getter property to define on aObject.
|
||||
* @param aPreference
|
||||
* The name of the preference to read.
|
||||
* @param aDefaultValue
|
||||
* The default value to use, if the preference is not defined.
|
||||
*/
|
||||
defineLazyPreferenceGetter: function XPCU_defineLazyPreferenceGetter(
|
||||
aObject, aName, aPreference, aDefaultValue = null)
|
||||
{
|
||||
// Note: We need to keep a reference to this observer alive as long
|
||||
// as aObject is alive. This means that all of our getters need to
|
||||
// explicitly close over the variable that holds the object, and we
|
||||
// cannot define a value in place of a getter after we read the
|
||||
// preference.
|
||||
let observer = {
|
||||
QueryInterface: this.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
|
||||
|
||||
value: undefined,
|
||||
|
||||
observe(subject, topic, data) {
|
||||
if (data == aPreference) {
|
||||
this.value = undefined;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
let defineGetter = get => {
|
||||
Object.defineProperty(aObject, aName, {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get,
|
||||
});
|
||||
};
|
||||
|
||||
function lazyGetter() {
|
||||
if (observer.value === undefined) {
|
||||
observer.value = Preferences.get(aPreference, aDefaultValue);
|
||||
}
|
||||
return observer.value;
|
||||
}
|
||||
|
||||
defineGetter(() => {
|
||||
Services.prefs.addObserver(aPreference, observer, true);
|
||||
|
||||
defineGetter(lazyGetter);
|
||||
return lazyGetter();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Convenience access to category manager
|
||||
*/
|
||||
@ -382,6 +439,11 @@ this.XPCOMUtils = {
|
||||
},
|
||||
};
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
|
||||
"resource://gre/modules/Preferences.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
/**
|
||||
* Helper for XPCOMUtils.generateQI to avoid leaks - see bug 381651#c1
|
||||
*/
|
||||
|
@ -8,6 +8,7 @@
|
||||
* This file tests the methods on XPCOMUtils.jsm.
|
||||
*/
|
||||
|
||||
Components.utils.import("resource://gre/modules/Preferences.jsm");
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const Cc = Components.classes;
|
||||
@ -116,6 +117,44 @@ add_test(function test_defineLazyServiceGetter()
|
||||
});
|
||||
|
||||
|
||||
add_test(function test_defineLazyPreferenceGetter()
|
||||
{
|
||||
const PREF = "xpcomutils.test.pref";
|
||||
|
||||
let obj = {};
|
||||
XPCOMUtils.defineLazyPreferenceGetter(obj, "pref", PREF, "defaultValue");
|
||||
|
||||
|
||||
equal(obj.pref, "defaultValue", "Should return the default value before pref is set");
|
||||
|
||||
Preferences.set(PREF, "currentValue");
|
||||
|
||||
|
||||
do_print("Create second getter on new object");
|
||||
|
||||
obj = {};
|
||||
XPCOMUtils.defineLazyPreferenceGetter(obj, "pref", PREF, "defaultValue");
|
||||
|
||||
|
||||
equal(obj.pref, "currentValue", "Should return the current value on initial read when pref is already set");
|
||||
|
||||
Preferences.set(PREF, "newValue");
|
||||
|
||||
equal(obj.pref, "newValue", "Should return new value after preference change");
|
||||
|
||||
Preferences.set(PREF, "currentValue");
|
||||
|
||||
equal(obj.pref, "currentValue", "Should return new value after second preference change");
|
||||
|
||||
|
||||
Preferences.reset(PREF);
|
||||
|
||||
equal(obj.pref, "defaultValue", "Should return default value after pref is reset");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
|
||||
add_test(function test_categoryRegistration()
|
||||
{
|
||||
const CATEGORY_NAME = "test-cat";
|
||||
|
Loading…
Reference in New Issue
Block a user