Restartless Add-ons – Default Preferences

I saw a neat technique in Bug 564675 for creating default preferences in bootstrapped add-ons. Edward Lee posted a link to some code he uses for a bootstrapped add-on. Essentailly, the default preference branch is writable, but not permanent. This is a good thing for bootstrapped add-ons. The add-on should write it’s default preferences every time it loads and the preferences disappear when the session ends. The code looks like:


const PREF_BRANCH = "extensions.myaddon.";
const PREFS = {
  someIntPref: 1,
  someStringPref: "some text value"
};

function setDefaultPrefs() {
  let branch = Services.prefs.getDefaultBranch(PREF_BRANCH);
  for (let [key, val] in Iterator(PREFS)) {
    switch (typeof val) {
      case "boolean":
        branch.setBoolPref(key, val);
        break;
      case "number":
        branch.setIntPref(key, val);
        break;
      case "string":
        branch.setCharPref(key, val);
        break;
    }
  }
}

function startup(aData, aReason) {
  // Always set the default prefs as they disappear on restart
  setDefaultPrefs();
  ...
}

I haven’t tested to see if there is a clean way to remove these preferences when a bootstrapped add-on is disabled or uninstalled. The default preferences will likely still hang around until a shutdown occurs.

We’re starting to amass a sizable collection of code snippets for bootstrapped add-ons. I think a new section in the MDC Code Snippets area might be needed.

4 Comments

  1. Wladimir Palant said,

    January 25, 2011 @ 4:59 am

    I think that you can remove them by means of clearUserPref(). The actually useful code snippet would be one locating the file in the extension’s defaults/preferences directory and loading it with the pref() function redefined as necessary (different function for startup and shutdown). That’s the backwards-compatible approach. If you already have the preferences as a JS object anyway you probably don’t need default preferences anyway.

  2. Neil Rashbrook said,

    January 25, 2011 @ 6:07 am

    I don’t think that the the reload-default-prefs observer notification deletes the old default preferences. It would be convenient if it did, though.

  3. Dimitri Saltanov said,

    February 2, 2011 @ 12:19 pm

    Default values will indeed hang around until application restart. You cannot clear them with branch.clearUserPref() because this method operates on the user tree, accessed with Services.prefs.getBranch(), rather than on the default (fall-back) tree, accessed with .getDefaultBranch(). I guess the only sure way to programmatically wipe out default preferences once they are created is to use branch.deleteBranch(). Though I hardly see a reason to delete default prefs as they will naturally die off after restart. User prefs, however, should be deleted on uninstall, because they are permanent (mirrored in the profile/prefs.js) and are not deleted by the app.

    Concerning the snippet, I see two problems that would make it wrong to recommend it as a generic approach to preferences without a lot of warnings: (1) branch.setIntPref() will only store integers, so using it to process everything typeof === number would be misleading, and (2) AFAIK, branch.setCharPref() is not designed to store unicode strings, so it may be unsafe to use for everything typeof === string verbatim. (1) is easily solved by either distinguishing between integers and floats and storing floats as strings, or simply storing any javascript number as a string. For (2), a number of workarounds would work, all requiring some additional processing; the ‘right thing’ one is to use branch.setComplexValue() instead of .setCharPref(), embedding the incoming string value in Ci.nsISupportsString beforehand. I would guess that the chrome addons infrasturcture performs this steps automatically.

    An addition that might be valuable in a generic snippet would be the ability to also store arbitrary non-null non-primitives (typeof === object) using JSON – quite a few extensions do this already, as well as the toolkit itself. In case the prefs are used merely to store some small important configuration data, like in the above case, just dumping the PREFS structure wholesale into a single unicode enabled pref string might prove to be the most convenient thing to do.

    If you are going to create a snippet base for bootstrap add-ons on MDC I could contribute some bits and pieces.

  4. Chris said,

    February 14, 2011 @ 10:00 am

    Hi,

    I have found XULExplorer. Some bugs I have found too.
    And some wishes :)
    My question is, is the project still alive?

    Regards Chris

RSS feed for comments on this post