| 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 |