addon-sdk/source/lib/sdk/preferences/service.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/addon-sdk/source/lib/sdk/preferences/service.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,178 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +"use strict";
     1.9 +
    1.10 +module.metadata = {
    1.11 +  "stability": "unstable"
    1.12 +};
    1.13 +
    1.14 +// The minimum and maximum integers that can be set as preferences.
    1.15 +// The range of valid values is narrower than the range of valid JS values
    1.16 +// because the native preferences code treats integers as NSPR PRInt32s,
    1.17 +// which are 32-bit signed integers on all platforms.
    1.18 +const MAX_INT = 0x7FFFFFFF;
    1.19 +const MIN_INT = -0x80000000;
    1.20 +
    1.21 +const {Cc,Ci,Cr} = require("chrome");
    1.22 +
    1.23 +const prefService = Cc["@mozilla.org/preferences-service;1"].
    1.24 +                getService(Ci.nsIPrefService);
    1.25 +const prefSvc = prefService.getBranch(null);
    1.26 +const defaultBranch = prefService.getDefaultBranch(null);
    1.27 +
    1.28 +function Branch(branchName) {
    1.29 +  function getPrefKeys() {
    1.30 +    return keys(branchName).map(function(key) {
    1.31 +      return key.replace(branchName, "");
    1.32 +    });
    1.33 +  }
    1.34 +
    1.35 +  return Proxy.create({
    1.36 +    get: function(receiver, pref) {
    1.37 +      return get(branchName + pref);
    1.38 +    },
    1.39 +    set: function(receiver, pref, val) {
    1.40 +      set(branchName + pref, val);
    1.41 +    },
    1.42 +    delete: function(pref) {
    1.43 +      reset(branchName + pref);
    1.44 +      return true;
    1.45 +    },
    1.46 +    has: function hasPrefKey(pref) {
    1.47 +      return has(branchName + pref)
    1.48 +    },
    1.49 +    getPropertyDescriptor: function(name) {
    1.50 +      return {
    1.51 +        value: get(branchName + name)
    1.52 +      };
    1.53 +    },
    1.54 +    enumerate: getPrefKeys,
    1.55 +    keys: getPrefKeys
    1.56 +  }, Branch.prototype);
    1.57 +}
    1.58 +
    1.59 +function get(name, defaultValue) {
    1.60 +  switch (prefSvc.getPrefType(name)) {
    1.61 +  case Ci.nsIPrefBranch.PREF_STRING:
    1.62 +    return prefSvc.getComplexValue(name, Ci.nsISupportsString).data;
    1.63 +
    1.64 +  case Ci.nsIPrefBranch.PREF_INT:
    1.65 +    return prefSvc.getIntPref(name);
    1.66 +
    1.67 +  case Ci.nsIPrefBranch.PREF_BOOL:
    1.68 +    return prefSvc.getBoolPref(name);
    1.69 +
    1.70 +  case Ci.nsIPrefBranch.PREF_INVALID:
    1.71 +    return defaultValue;
    1.72 +
    1.73 +  default:
    1.74 +    // This should never happen.
    1.75 +    throw new Error("Error getting pref " + name +
    1.76 +                    "; its value's type is " +
    1.77 +                    prefSvc.getPrefType(name) +
    1.78 +                    ", which I don't know " +
    1.79 +                    "how to handle.");
    1.80 +  }
    1.81 +}
    1.82 +exports.get = get;
    1.83 +
    1.84 +function set(name, value) {
    1.85 +  var prefType;
    1.86 +  if (typeof value != "undefined" && value != null)
    1.87 +    prefType = value.constructor.name;
    1.88 +
    1.89 +  switch (prefType) {
    1.90 +  case "String":
    1.91 +    {
    1.92 +      var string = Cc["@mozilla.org/supports-string;1"].
    1.93 +                   createInstance(Ci.nsISupportsString);
    1.94 +      string.data = value;
    1.95 +      prefSvc.setComplexValue(name, Ci.nsISupportsString, string);
    1.96 +    }
    1.97 +    break;
    1.98 +
    1.99 +  case "Number":
   1.100 +    // We throw if the number is outside the range or not an integer, since
   1.101 +    // the result will not be what the consumer wanted to store.
   1.102 +    if (value > MAX_INT || value < MIN_INT)
   1.103 +      throw new Error("you cannot set the " + name +
   1.104 +                      " pref to the number " + value +
   1.105 +                      ", as number pref values must be in the signed " +
   1.106 +                      "32-bit integer range -(2^31) to 2^31-1.  " +
   1.107 +                      "To store numbers outside that range, store " +
   1.108 +                      "them as strings.");
   1.109 +    if (value % 1 != 0)
   1.110 +      throw new Error("cannot store non-integer number: " + value);
   1.111 +    prefSvc.setIntPref(name, value);
   1.112 +    break;
   1.113 +
   1.114 +  case "Boolean":
   1.115 +    prefSvc.setBoolPref(name, value);
   1.116 +    break;
   1.117 +
   1.118 +  default:
   1.119 +    throw new Error("can't set pref " + name + " to value '" + value +
   1.120 +                    "'; it isn't a string, integer, or boolean");
   1.121 +  }
   1.122 +}
   1.123 +exports.set = set;
   1.124 +
   1.125 +function has(name) {
   1.126 +  return (prefSvc.getPrefType(name) != Ci.nsIPrefBranch.PREF_INVALID);
   1.127 +}
   1.128 +exports.has = has;
   1.129 +
   1.130 +function keys(root) {
   1.131 +  return prefSvc.getChildList(root);
   1.132 +}
   1.133 +exports.keys = keys;
   1.134 +
   1.135 +function isSet(name) {
   1.136 +  return (has(name) && prefSvc.prefHasUserValue(name));
   1.137 +}
   1.138 +exports.isSet = isSet;
   1.139 +
   1.140 +function reset(name) {
   1.141 +  try {
   1.142 +    prefSvc.clearUserPref(name);
   1.143 +  }
   1.144 +  catch (e) {
   1.145 +    // The pref service throws NS_ERROR_UNEXPECTED when the caller tries
   1.146 +    // to reset a pref that doesn't exist or is already set to its default
   1.147 +    // value.  This interface fails silently in those cases, so callers
   1.148 +    // can unconditionally reset a pref without having to check if it needs
   1.149 +    // resetting first or trap exceptions after the fact.  It passes through
   1.150 +    // other exceptions, however, so callers know about them, since we don't
   1.151 +    // know what other exceptions might be thrown and what they might mean.
   1.152 +    if (e.result != Cr.NS_ERROR_UNEXPECTED) {
   1.153 +      throw e;
   1.154 +    }
   1.155 +  }
   1.156 +}
   1.157 +exports.reset = reset;
   1.158 +
   1.159 +function getLocalized(name, defaultValue) {
   1.160 +  let value = null;
   1.161 +  try {
   1.162 +    value = prefSvc.getComplexValue(name, Ci.nsIPrefLocalizedString).data;
   1.163 +  }
   1.164 +  finally {
   1.165 +    return value || defaultValue;
   1.166 +  }
   1.167 +}
   1.168 +exports.getLocalized = getLocalized;
   1.169 +
   1.170 +function setLocalized(name, value) {
   1.171 +  // We can't use `prefs.set` here as we have to use `getDefaultBranch`
   1.172 +  // (instead of `getBranch`) in order to have `mIsDefault` set to true, here:
   1.173 +  // http://mxr.mozilla.org/mozilla-central/source/modules/libpref/src/nsPrefBranch.cpp#233
   1.174 +  // Otherwise, we do not enter into this expected condition:
   1.175 +  // http://mxr.mozilla.org/mozilla-central/source/modules/libpref/src/nsPrefBranch.cpp#244
   1.176 +  defaultBranch.setCharPref(name, value);
   1.177 +}
   1.178 +exports.setLocalized = setLocalized;
   1.179 +
   1.180 +exports.Branch = Branch;
   1.181 +

mercurial