| OLD | NEW |
| (Empty) |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| 4 | |
| 5 let {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); | |
| 6 let {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {}); | |
| 7 | |
| 8 let {addonRoot, addonName} = require("info"); | |
| 9 let branchName = "extensions." + addonName + "."; | |
| 10 let branch = Services.prefs.getBranch(branchName); | |
| 11 let preconfiguredBranch = | |
| 12 Services.prefs.getBranch(branchName + "preconfigured."); | |
| 13 let ignorePrefChanges = false; | |
| 14 | |
| 15 function init() | |
| 16 { | |
| 17 // Load default preferences and set up properties for them | |
| 18 let defaultBranch = Services.prefs.getDefaultBranch(branchName); | |
| 19 | |
| 20 let prefsData = require("prefs.json"); | |
| 21 let defaults = prefsData.defaults; | |
| 22 let preconfigurable = new Set(prefsData.preconfigurable); | |
| 23 for (let pref in defaults) | |
| 24 { | |
| 25 let value = defaults[pref]; | |
| 26 let [getter, setter] = typeMap[typeof value]; | |
| 27 if (preconfigurable.has(pref)) | |
| 28 { | |
| 29 try | |
| 30 { | |
| 31 value = getter(preconfiguredBranch, pref); | |
| 32 } | |
| 33 catch (e) {} | |
| 34 } | |
| 35 setter(defaultBranch, pref, value); | |
| 36 defineProperty(pref, false, getter, setter); | |
| 37 } | |
| 38 | |
| 39 // Add preference change observer | |
| 40 try | |
| 41 { | |
| 42 branch.QueryInterface(Ci.nsIPrefBranch2).addObserver("", Prefs, true); | |
| 43 onShutdown.add(() => branch.removeObserver("", Prefs)); | |
| 44 } | |
| 45 catch (e) | |
| 46 { | |
| 47 Cu.reportError(e); | |
| 48 } | |
| 49 } | |
| 50 | |
| 51 /** | |
| 52 * Sets up getter/setter on Prefs object for preference. | |
| 53 */ | |
| 54 function defineProperty(/**String*/ name, defaultValue, /**Function*/ readFunc,
/**Function*/ writeFunc) | |
| 55 { | |
| 56 let value = defaultValue; | |
| 57 Prefs["_update_" + name] = () => | |
| 58 { | |
| 59 try | |
| 60 { | |
| 61 value = readFunc(branch, name); | |
| 62 triggerListeners(name); | |
| 63 } | |
| 64 catch(e) | |
| 65 { | |
| 66 Cu.reportError(e); | |
| 67 } | |
| 68 }; | |
| 69 Object.defineProperty(Prefs, name, { | |
| 70 enumerable: true, | |
| 71 get: () => value, | |
| 72 set: (newValue) => | |
| 73 { | |
| 74 if (value == newValue) | |
| 75 return value; | |
| 76 | |
| 77 try | |
| 78 { | |
| 79 ignorePrefChanges = true; | |
| 80 writeFunc(branch, name, newValue); | |
| 81 value = newValue; | |
| 82 Services.prefs.savePrefFile(null); | |
| 83 triggerListeners(name); | |
| 84 } | |
| 85 catch(e) | |
| 86 { | |
| 87 Cu.reportError(e); | |
| 88 } | |
| 89 finally | |
| 90 { | |
| 91 ignorePrefChanges = false; | |
| 92 } | |
| 93 return value; | |
| 94 } | |
| 95 }); | |
| 96 Prefs["_update_" + name](); | |
| 97 } | |
| 98 | |
| 99 let listeners = []; | |
| 100 function triggerListeners(/**String*/ name) | |
| 101 { | |
| 102 for (let i = 0; i < listeners.length; i++) | |
| 103 { | |
| 104 try | |
| 105 { | |
| 106 listeners[i](name); | |
| 107 } | |
| 108 catch(e) | |
| 109 { | |
| 110 Cu.reportError(e); | |
| 111 } | |
| 112 } | |
| 113 } | |
| 114 | |
| 115 /** | |
| 116 * Manages the preferences for an extension, object properties corresponding | |
| 117 * to extension's preferences are added automatically. Setting the property | |
| 118 * will automatically change the preference, external preference changes are | |
| 119 * also recognized automatically. | |
| 120 */ | |
| 121 let Prefs = exports.Prefs = | |
| 122 { | |
| 123 /** | |
| 124 * Migrates an old preference to a new name. | |
| 125 */ | |
| 126 migrate: function(/**String*/ oldName, /**String*/ newName) | |
| 127 { | |
| 128 if (newName in this && Services.prefs.prefHasUserValue(oldName)) | |
| 129 { | |
| 130 let [getter, setter] = typeMap[typeof this[newName]]; | |
| 131 try | |
| 132 { | |
| 133 this[newName] = getter(Services.prefs, oldName); | |
| 134 } catch(e) {} | |
| 135 Services.prefs.clearUserPref(oldName); | |
| 136 } | |
| 137 }, | |
| 138 | |
| 139 /** | |
| 140 * Adds a preferences listener that will be fired whenever a preference | |
| 141 * changes. | |
| 142 */ | |
| 143 addListener: function(/**Function*/ listener) | |
| 144 { | |
| 145 if (listeners.indexOf(listener) < 0) | |
| 146 listeners.push(listener); | |
| 147 }, | |
| 148 | |
| 149 /** | |
| 150 * Removes a preferences listener. | |
| 151 */ | |
| 152 removeListener: function(/**Function*/ listener) | |
| 153 { | |
| 154 let index = listeners.indexOf(listener); | |
| 155 if (index >= 0) | |
| 156 listeners.splice(index, 1); | |
| 157 }, | |
| 158 | |
| 159 observe: function(subject, topic, data) | |
| 160 { | |
| 161 if (ignorePrefChanges || topic != "nsPref:changed") | |
| 162 return; | |
| 163 | |
| 164 if ("_update_" + data in this) | |
| 165 this["_update_" + data](); | |
| 166 }, | |
| 167 | |
| 168 QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference, Ci.nsIObse
rver]) | |
| 169 }; | |
| 170 | |
| 171 let getIntPref = (branch, pref) => branch.getIntPref(pref); | |
| 172 let setIntPref = (branch, pref, newValue) => branch.setIntPref(pref, newValue); | |
| 173 | |
| 174 let getBoolPref = (branch, pref) => branch.getBoolPref(pref); | |
| 175 let setBoolPref = (branch, pref, newValue) => branch.setBoolPref(pref, newValue)
; | |
| 176 | |
| 177 let getCharPref = (branch, pref) => branch.getComplexValue(pref, Ci.nsISupportsS
tring).data; | |
| 178 let setCharPref = (branch, pref, newValue) => | |
| 179 { | |
| 180 let str = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsSt
ring); | |
| 181 str.data = newValue; | |
| 182 branch.setComplexValue(pref, Ci.nsISupportsString, str); | |
| 183 }; | |
| 184 | |
| 185 let getJSONPref = (branch, pref) => JSON.parse(getCharPref(branch, pref)); | |
| 186 let setJSONPref = (branch, pref, newValue) => setCharPref(branch, pref, JSON.str
ingify(newValue)); | |
| 187 | |
| 188 // Getter/setter functions for difference preference types | |
| 189 let typeMap = | |
| 190 { | |
| 191 boolean: [getBoolPref, setBoolPref], | |
| 192 number: [getIntPref, setIntPref], | |
| 193 string: [getCharPref, setCharPref], | |
| 194 object: [getJSONPref, setJSONPref] | |
| 195 }; | |
| 196 | |
| 197 init(); | |
| OLD | NEW |