summaryrefslogtreecommitdiff
path: root/toolkit/jetpack/sdk/preferences/service.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/jetpack/sdk/preferences/service.js')
-rw-r--r--toolkit/jetpack/sdk/preferences/service.js137
1 files changed, 137 insertions, 0 deletions
diff --git a/toolkit/jetpack/sdk/preferences/service.js b/toolkit/jetpack/sdk/preferences/service.js
new file mode 100644
index 0000000000..231cd8e140
--- /dev/null
+++ b/toolkit/jetpack/sdk/preferences/service.js
@@ -0,0 +1,137 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
+
+module.metadata = {
+ "stability": "unstable"
+};
+
+// The minimum and maximum integers that can be set as preferences.
+// The range of valid values is narrower than the range of valid JS values
+// because the native preferences code treats integers as NSPR PRInt32s,
+// which are 32-bit signed integers on all platforms.
+const MAX_INT = 0x7FFFFFFF;
+const MIN_INT = -0x80000000;
+
+const {Cc,Ci,Cr} = require("chrome");
+
+const prefService = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService);
+const prefSvc = prefService.getBranch(null);
+const defaultBranch = prefService.getDefaultBranch(null);
+
+const { Preferences } = require("resource://gre/modules/Preferences.jsm");
+const prefs = new Preferences({});
+
+const branchKeys = branchName =>
+ keys(branchName).map($ => $.replace(branchName, ""));
+
+const Branch = function(branchName) {
+ return new Proxy(Branch.prototype, {
+ getOwnPropertyDescriptor(target, name, receiver) {
+ return {
+ configurable: true,
+ enumerable: true,
+ writable: false,
+ value: this.get(target, name, receiver)
+ };
+ },
+ ownKeys(target) {
+ return branchKeys(branchName);
+ },
+ get(target, name, receiver) {
+ return get(`${branchName}${name}`);
+ },
+ set(target, name, value, receiver) {
+ set(`${branchName}${name}`, value);
+ return true;
+ },
+ has(target, name) {
+ return this.hasOwn(target, name);
+ },
+ hasOwn(target, name) {
+ return has(`${branchName}${name}`);
+ },
+ deleteProperty(target, name) {
+ reset(`${branchName}${name}`);
+ return true;
+ }
+ });
+}
+
+
+function get(name, defaultValue) {
+ return prefs.get(name, defaultValue);
+}
+exports.get = get;
+
+
+function set(name, value) {
+ var prefType;
+ if (typeof value != "undefined" && value != null)
+ prefType = value.constructor.name;
+
+ switch (prefType) {
+ case "Number":
+ if (value % 1 != 0)
+ throw new Error("cannot store non-integer number: " + value);
+ }
+
+ prefs.set(name, value);
+}
+exports.set = set;
+
+const has = prefs.has.bind(prefs)
+exports.has = has;
+
+function keys(root) {
+ return prefSvc.getChildList(root);
+}
+exports.keys = keys;
+
+const isSet = prefs.isSet.bind(prefs);
+exports.isSet = isSet;
+
+function reset(name) {
+ try {
+ prefSvc.clearUserPref(name);
+ }
+ catch (e) {
+ // The pref service throws NS_ERROR_UNEXPECTED when the caller tries
+ // to reset a pref that doesn't exist or is already set to its default
+ // value. This interface fails silently in those cases, so callers
+ // can unconditionally reset a pref without having to check if it needs
+ // resetting first or trap exceptions after the fact. It passes through
+ // other exceptions, however, so callers know about them, since we don't
+ // know what other exceptions might be thrown and what they might mean.
+ if (e.result != Cr.NS_ERROR_UNEXPECTED) {
+ throw e;
+ }
+ }
+}
+exports.reset = reset;
+
+function getLocalized(name, defaultValue) {
+ let value = null;
+ try {
+ value = prefSvc.getComplexValue(name, Ci.nsIPrefLocalizedString).data;
+ }
+ finally {
+ return value || defaultValue;
+ }
+}
+exports.getLocalized = getLocalized;
+
+function setLocalized(name, value) {
+ // We can't use `prefs.set` here as we have to use `getDefaultBranch`
+ // (instead of `getBranch`) in order to have `mIsDefault` set to true, here:
+ // http://mxr.mozilla.org/mozilla-central/source/modules/libpref/src/nsPrefBranch.cpp#233
+ // Otherwise, we do not enter into this expected condition:
+ // http://mxr.mozilla.org/mozilla-central/source/modules/libpref/src/nsPrefBranch.cpp#244
+ defaultBranch.setCharPref(name, value);
+}
+exports.setLocalized = setLocalized;
+
+exports.Branch = Branch;
+