Bug 1029097 - ViewHelpers.Prefs should have a way of clearing the cached preferences, r=rcampbell
authorVictor Porof <vporof@mozilla.com>
Tue, 24 Jun 2014 21:45:47 -0400
changeset 190653 c7e9cd887d3d9e3a6913adf2e51495834163b7cf
parent 190652 408f1e04c1c4538297a5c6c0c10ed8664ae9b09a
child 190654 bb723b1668ecd2f86666e4ccdd9ca58f3010a518
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersrcampbell
bugs1029097
milestone33.0a1
Bug 1029097 - ViewHelpers.Prefs should have a way of clearing the cached preferences, r=rcampbell
browser/devtools/netmonitor/test/browser_net_prefs-and-l10n.js
browser/devtools/shared/test/browser.ini
browser/devtools/shared/test/browser_prefs.js
browser/devtools/shared/widgets/ViewHelpers.jsm
--- a/browser/devtools/netmonitor/test/browser_net_prefs-and-l10n.js
+++ b/browser/devtools/netmonitor/test/browser_net_prefs-and-l10n.js
@@ -30,17 +30,17 @@ function test() {
       is(L10N.getFormatStr("networkMenu.totalMS", "foo"),
         stringBundle.formatStringFromName("networkMenu.totalMS", ["foo"], 1),
         "The getFormatStr() method didn't return the expected string.");
     }
 
     function testPrefs() {
       let { Prefs } = aMonitor.panelWin;
 
-      is(Prefs.root, "devtools.netmonitor",
+      is(Prefs._root, "devtools.netmonitor",
         "The preferences object should have a correct root path.");
 
       is(Prefs.networkDetailsWidth,
         Services.prefs.getIntPref("devtools.netmonitor.panes-network-details-width"),
         "Getting a pref should work correctly.");
 
       let previousValue = Prefs.networkDetailsWidth;
       let bogusValue = ~~(Math.random() * 100);
--- a/browser/devtools/shared/test/browser.ini
+++ b/browser/devtools/shared/test/browser.ini
@@ -26,16 +26,17 @@ support-files =
 [browser_graphs-11.js]
 [browser_graphs-12.js]
 [browser_graphs-13.js]
 [browser_graphs-14.js]
 [browser_layoutHelpers.js]
 [browser_layoutHelpers-getBoxQuads.js]
 [browser_observableobject.js]
 [browser_outputparser.js]
+[browser_prefs.js]
 [browser_require_basic.js]
 [browser_spectrum.js]
 [browser_tableWidget_basic.js]
 [browser_tableWidget_keyboard_interaction.js]
 [browser_tableWidget_mouse_interaction.js]
 [browser_telemetry_button_paintflashing.js]
 [browser_telemetry_button_responsive.js]
 [browser_telemetry_button_scratchpad.js]
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/test/browser_prefs.js
@@ -0,0 +1,33 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Tests that ViewHelpers.Prefs work properly.
+
+let {ViewHelpers} = Cu.import("resource:///modules/devtools/ViewHelpers.jsm", {});
+
+function test() {
+  let Prefs = new ViewHelpers.Prefs("devtools.debugger", {
+    "foo": ["Bool", "enabled"]
+  });
+
+  let originalPrefValue = Services.prefs.getBoolPref("devtools.debugger.enabled");
+  is(Prefs.foo, originalPrefValue, "The pref value was correctly fetched.");
+
+  Prefs.foo = !originalPrefValue;
+  is(Prefs.foo, !originalPrefValue,
+    "The pref was was correctly changed (1).");
+  is(Services.prefs.getBoolPref("devtools.debugger.enabled"), !originalPrefValue,
+    "The pref was was correctly changed (2).");
+
+  Services.prefs.setBoolPref("devtools.debugger.enabled", originalPrefValue);
+  info("The pref value was reset.");
+
+  is(Prefs.foo, !originalPrefValue,
+    "The cached pref value hasn't changed yet.");
+
+  Prefs.refresh();
+  is(Prefs.foo, originalPrefValue,
+    "The cached pref value has changed now.");
+
+  finish();
+}
--- a/browser/devtools/shared/widgets/ViewHelpers.jsm
+++ b/browser/devtools/shared/widgets/ViewHelpers.jsm
@@ -389,49 +389,53 @@ ViewHelpers.L10N.prototype = {
  *   let aux = prefs.myCharPref;
  *
  * @param string aPrefsRoot
  *        The root path to the required preferences branch.
  * @param object aPrefsObject
  *        An object containing { accessorName: [prefType, prefName] } keys.
  */
 ViewHelpers.Prefs = function(aPrefsRoot = "", aPrefsObject = {}) {
-  this.root = aPrefsRoot;
+  this._root = aPrefsRoot;
+  this._cache = new Map();
 
   for (let accessorName in aPrefsObject) {
     let [prefType, prefName] = aPrefsObject[accessorName];
     this.map(accessorName, prefType, prefName);
   }
 };
 
 ViewHelpers.Prefs.prototype = {
   /**
    * Helper method for getting a pref value.
    *
    * @param string aType
    * @param string aPrefName
    * @return any
    */
   _get: function(aType, aPrefName) {
-    if (this[aPrefName] === undefined) {
-      this[aPrefName] = Services.prefs["get" + aType + "Pref"](aPrefName);
+    let cachedPref = this._cache.get(aPrefName);
+    if (cachedPref !== undefined) {
+      return cachedPref;
     }
-    return this[aPrefName];
+    let value = Services.prefs["get" + aType + "Pref"](aPrefName);
+    this._cache.set(aPrefName, value);
+    return value;
   },
 
   /**
    * Helper method for setting a pref value.
    *
    * @param string aType
    * @param string aPrefName
    * @param any aValue
    */
   _set: function(aType, aPrefName, aValue) {
     Services.prefs["set" + aType + "Pref"](aPrefName, aValue);
-    this[aPrefName] = aValue;
+    this._cache.set(aPrefName, aValue);
   },
 
   /**
    * Maps a property name to a pref, defining lazy getters and setters.
    * Supported types are "Bool", "Char", "Int" and "Json" (which is basically
    * just sugar for "Char" using the standard JSON serializer).
    *
    * @param string aAccessorName
@@ -441,19 +445,26 @@ ViewHelpers.Prefs.prototype = {
    */
   map: function(aAccessorName, aType, aPrefName, aSerializer = { in: e => e, out: e => e }) {
     if (aType == "Json") {
       this.map(aAccessorName, "Char", aPrefName, { in: JSON.parse, out: JSON.stringify });
       return;
     }
 
     Object.defineProperty(this, aAccessorName, {
-      get: () => aSerializer.in(this._get(aType, [this.root, aPrefName].join("."))),
-      set: (e) => this._set(aType, [this.root, aPrefName].join("."), aSerializer.out(e))
+      get: () => aSerializer.in(this._get(aType, [this._root, aPrefName].join("."))),
+      set: (e) => this._set(aType, [this._root, aPrefName].join("."), aSerializer.out(e))
     });
+  },
+
+  /**
+   * Clears all the cached preferences' values.
+   */
+  refresh: function() {
+    this._cache.clear();
   }
 };
 
 /**
  * A generic Item is used to describe children present in a Widget.
  *
  * This is basically a very thin wrapper around an nsIDOMNode, with a few
  * characteristics, like a `value` and an `attachment`.