toolkit/components/url-classifier/content/moz/preferences.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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/.
     6 // Class for manipulating preferences. Aside from wrapping the pref
     7 // service, useful functionality includes:
     8 //
     9 // - abstracting prefobserving so that you can observe preferences
    10 //   without implementing nsIObserver 
    11 // 
    12 // - getters that return a default value when the pref doesn't exist 
    13 //   (instead of throwing)
    14 // 
    15 // - get-and-set getters
    16 //
    17 // Example:
    18 // 
    19 // var p = new PROT_Preferences();
    20 // dump(p.getPref("some-true-pref"));     // shows true
    21 // dump(p.getPref("no-such-pref", true)); // shows true   
    22 // dump(p.getPref("no-such-pref", null)); // shows null
    23 //
    24 // function observe(prefThatChanged) {
    25 //   dump("Pref changed: " + prefThatChanged);
    26 // };
    27 //
    28 // p.addObserver("somepref", observe);
    29 // p.setPref("somepref", true);            // dumps
    30 // p.removeObserver("somepref", observe);
    31 //
    32 // TODO: should probably have the prefobserver pass in the new and old
    33 //       values
    35 // TODO(tc): Maybe remove this class and just call natively since we're no
    36 //           longer an extension.
    38 /**
    39  * A class that wraps the preferences service.
    40  *
    41  * @param opt_startPoint        A starting point on the prefs tree to resolve 
    42  *                              names passed to setPref and getPref.
    43  *
    44  * @param opt_useDefaultPranch  Set to true to work against the default 
    45  *                              preferences tree instead of the profile one.
    46  *
    47  * @constructor
    48  */
    49 function G_Preferences(opt_startPoint, opt_getDefaultBranch) {
    50   this.debugZone = "prefs";
    51   this.observers_ = {};
    52   this.getDefaultBranch_ = !!opt_getDefaultBranch;
    54   this.startPoint_ = opt_startPoint || null;
    55 }
    57 G_Preferences.setterMap_ = { "string": "setCharPref",
    58                              "boolean": "setBoolPref",
    59                              "number": "setIntPref" };
    61 G_Preferences.getterMap_ = {};
    62 G_Preferences.getterMap_[Ci.nsIPrefBranch.PREF_STRING] = "getCharPref";
    63 G_Preferences.getterMap_[Ci.nsIPrefBranch.PREF_BOOL] = "getBoolPref";
    64 G_Preferences.getterMap_[Ci.nsIPrefBranch.PREF_INT] = "getIntPref";
    66 G_Preferences.prototype.__defineGetter__('prefs_', function() {
    67   var prefs;
    68   var prefSvc = Cc["@mozilla.org/preferences-service;1"]
    69                   .getService(Ci.nsIPrefService);
    71   if (this.getDefaultBranch_) {
    72     prefs = prefSvc.getDefaultBranch(this.startPoint_);
    73   } else {
    74     prefs = prefSvc.getBranch(this.startPoint_);
    75   }
    77   // QI to prefs in case we want to add observers
    78   prefs.QueryInterface(Ci.nsIPrefBranchInternal);
    79   return prefs;
    80 });
    82 /**
    83  * Stores a key/value in a user preference. Valid types for val are string,
    84  * boolean, and number. Complex values are not yet supported (but feel free to
    85  * add them!).
    86  */
    87 G_Preferences.prototype.setPref = function(key, val) {
    88   var datatype = typeof(val);
    90   if (datatype == "number" && (val % 1 != 0)) {
    91     throw new Error("Cannot store non-integer numbers in preferences.");
    92   }
    94   var meth = G_Preferences.setterMap_[datatype];
    96   if (!meth) {
    97     throw new Error("Pref datatype {" + datatype + "} not supported.");
    98   }
   100   return this.prefs_[meth](key, val);
   101 }
   103 /**
   104  * Retrieves a user preference. Valid types for the value are the same as for
   105  * setPref. If the preference is not found, opt_default will be returned 
   106  * instead.
   107  */
   108 G_Preferences.prototype.getPref = function(key, opt_default) {
   109   var type = this.prefs_.getPrefType(key);
   111   // zero means that the specified pref didn't exist
   112   if (type == Ci.nsIPrefBranch.PREF_INVALID) {
   113     return opt_default;
   114   }
   116   var meth = G_Preferences.getterMap_[type];
   118   if (!meth) {
   119     throw new Error("Pref datatype {" + type + "} not supported.");
   120   }
   122   // If a pref has been cleared, it will have a valid type but won't
   123   // be gettable, so this will throw.
   124   try {
   125     return this.prefs_[meth](key);
   126   } catch(e) {
   127     return opt_default;
   128   }
   129 }
   131 /**
   132  * Delete a preference. 
   133  *
   134  * @param which Name of preference to obliterate
   135  */
   136 G_Preferences.prototype.clearPref = function(which) {
   137   try {
   138     // This throws if the pref doesn't exist, which is fine because a 
   139     // nonexistent pref is cleared
   140     this.prefs_.clearUserPref(which);
   141   } catch(e) {}
   142 }
   144 /**
   145  * Add an observer for a given pref.
   146  *
   147  * @param which String containing the pref to listen to
   148  * @param callback Function to be called when the pref changes. This
   149  *                 function will receive a single argument, a string 
   150  *                 holding the preference name that changed
   151  */
   152 G_Preferences.prototype.addObserver = function(which, callback) {
   153   // Need to store the observer we create so we can eventually unregister it
   154   if (!this.observers_[which])
   155     this.observers_[which] = { callbacks: [], observers: [] };
   157   /* only add an observer if the callback hasn't been registered yet */
   158   if (this.observers_[which].callbacks.indexOf(callback) == -1) {
   159     var observer = new G_PreferenceObserver(callback);
   160     this.observers_[which].callbacks.push(callback);
   161     this.observers_[which].observers.push(observer);
   162     this.prefs_.addObserver(which, observer, false /* strong reference */);
   163   }
   164 }
   166 /**
   167  * Remove an observer for a given pref.
   168  *
   169  * @param which String containing the pref to stop listening to
   170  * @param callback Function to remove as an observer
   171  */
   172 G_Preferences.prototype.removeObserver = function(which, callback) {
   173   var ix = this.observers_[which].callbacks.indexOf(callback);
   174   G_Assert(this, ix != -1, "Tried to unregister a nonexistent observer"); 
   175   this.observers_[which].callbacks.splice(ix, 1);
   176   var observer = this.observers_[which].observers.splice(ix, 1)[0];
   177   this.prefs_.removeObserver(which, observer);
   178 }
   180 /**
   181  * Remove all preference observers registered through this object.
   182  */
   183 G_Preferences.prototype.removeAllObservers = function() {
   184   for (var which in this.observers_) {
   185     for each (var observer in this.observers_[which].observers) {
   186       this.prefs_.removeObserver(which, observer);
   187     }
   188   }
   189   this.observers_ = {};
   190 }
   192 /**
   193  * Helper class that knows how to observe preference changes and
   194  * invoke a callback when they do
   195  *
   196  * @constructor
   197  * @param callback Function to call when the preference changes
   198  */
   199 function G_PreferenceObserver(callback) {
   200   this.debugZone = "prefobserver";
   201   this.callback_ = callback;
   202 }
   204 /**
   205  * Invoked by the pref system when a preference changes. Passes the
   206  * message along to the callback.
   207  *
   208  * @param subject The nsIPrefBranch that changed
   209  * @param topic String "nsPref:changed" (aka 
   210  *              NS_PREFBRANCH_PREFCHANGE_OBSERVER_ID -- but where does it
   211  *              live???)
   212  * @param data Name of the pref that changed
   213  */
   214 G_PreferenceObserver.prototype.observe = function(subject, topic, data) {
   215   G_Debug(this, "Observed pref change: " + data);
   216   this.callback_(data);
   217 }
   219 /**
   220  * XPCOM cruft
   221  *
   222  * @param iid Interface id of the interface the caller wants
   223  */
   224 G_PreferenceObserver.prototype.QueryInterface = function(iid) {
   225   if (iid.equals(Ci.nsISupports) || 
   226       iid.equals(Ci.nsIObserver) ||
   227       iid.equals(Ci.nsISupportsWeakReference))
   228     return this;
   229   throw Components.results.NS_ERROR_NO_INTERFACE;
   230 }
   232 #ifdef DEBUG
   233 // UNITTESTS
   234 function TEST_G_Preferences() {
   235   if (G_GDEBUG) {
   236     var z = "preferences UNITTEST";
   237     G_debugService.enableZone(z);
   238     G_Debug(z, "Starting");
   240     var p = new G_Preferences();
   242     var testPref = "test-preferences-unittest";
   243     var noSuchPref = "test-preferences-unittest-aypabtu";
   245     // Used to test observing
   246     var observeCount = 0;
   247     function observe(prefChanged) {
   248       G_Assert(z, prefChanged == testPref, "observer broken");
   249       observeCount++;
   250     };
   252     // Test setting, getting, and observing
   253     p.addObserver(testPref, observe);
   254     p.setPref(testPref, true);
   255     G_Assert(z, p.getPref(testPref), "get or set broken");
   256     G_Assert(z, observeCount == 1, "observer adding not working");
   258     p.removeObserver(testPref, observe);
   260     p.setPref(testPref, false);
   261     G_Assert(z, observeCount == 1, "observer removal not working");
   262     G_Assert(z, !p.getPref(testPref), "get broken");
   264     // Remember to clean up the prefs we've set, and test removing prefs 
   265     // while we're at it
   266     p.clearPref(noSuchPref);
   267     G_Assert(z, !p.getPref(noSuchPref, false), "clear broken");
   269     p.clearPref(testPref);
   271     G_Debug(z, "PASSED");
   272   }
   273 }
   274 #endif

mercurial