| Index: lib/prefs.js | 
| =================================================================== | 
| --- a/lib/prefs.js | 
| +++ b/lib/prefs.js | 
| @@ -214,6 +214,31 @@ | 
| */ | 
| let Prefs = exports.Prefs = { | 
| /** | 
| +   * Sets the given preference. | 
| +   * | 
| +   * @param {string} preference | 
| +   * @param {any}    value | 
| +   * @return {Promise} A promise that resolves when the underlying | 
| +                       browser.storage.local.set/remove() operation completes | 
| +   */ | 
| +  set(preference, value) | 
| +  { | 
| +    let defaultValue = defaults[preference]; | 
| + | 
| +    if (typeof value != typeof defaultValue) | 
| +      throw new Error("Attempt to change preference type"); | 
| + | 
| +    if (value == defaultValue) | 
| +    { | 
| +      delete overrides[preference]; | 
| +      return browser.storage.local.remove(prefToKey(preference)); | 
| +    } | 
| + | 
| +    overrides[preference] = value; | 
| +    return (customSave.get(preference) || savePref)(preference); | 
| +  }, | 
| + | 
| +  /** | 
| * Adds a callback that is called when the | 
| * value of a specified preference changed. | 
| * | 
| @@ -261,7 +286,7 @@ | 
|  | 
| function savePref(pref) | 
| { | 
| -  browser.storage.local.set({[prefToKey(pref)]: overrides[pref]}); | 
| +  return browser.storage.local.set({[prefToKey(pref)]: overrides[pref]}); | 
| } | 
|  | 
| let customSave = new Map(); | 
| @@ -275,24 +300,25 @@ | 
| let updateScheduled = false; | 
| customSave.set("blocked_total", pref => | 
| { | 
| -    if (updateScheduled) | 
| -      return; | 
| - | 
| -    let callback = () => | 
| +    if (!updateScheduled) | 
| { | 
| -      lastUpdate = performance.now(); | 
| -      updateScheduled = false; | 
| -      savePref(pref); | 
| -    }; | 
| +      let callback = () => | 
| +      { | 
| +        lastUpdate = performance.now(); | 
| +        updateScheduled = false; | 
| +        savePref(pref); | 
| +      }; | 
|  | 
| -    let timeElapsed = performance.now() - lastUpdate; | 
| -    if (timeElapsed < MIN_UPDATE_INTERVAL) | 
| -    { | 
| -      setTimeout(callback, MIN_UPDATE_INTERVAL - timeElapsed); | 
| -      updateScheduled = true; | 
| +      let timeElapsed = performance.now() - lastUpdate; | 
| +      if (timeElapsed < MIN_UPDATE_INTERVAL) | 
| +      { | 
| +        setTimeout(callback, MIN_UPDATE_INTERVAL - timeElapsed); | 
| +        updateScheduled = true; | 
| +      } | 
| +      else | 
| +        callback(); | 
| } | 
| -    else | 
| -      callback(); | 
| +    return Promise.resolve(); | 
| }); | 
| } | 
|  | 
| @@ -302,21 +328,7 @@ | 
| get() { return (pref in overrides ? overrides : defaults)[pref]; }, | 
| set(value) | 
| { | 
| -      let defaultValue = defaults[pref]; | 
| - | 
| -      if (typeof value != typeof defaultValue) | 
| -        throw new Error("Attempt to change preference type"); | 
| - | 
| -      if (value == defaultValue) | 
| -      { | 
| -        delete overrides[pref]; | 
| -        browser.storage.local.remove(prefToKey(pref)); | 
| -      } | 
| -      else | 
| -      { | 
| -        overrides[pref] = value; | 
| -        (customSave.get(pref) || savePref)(pref); | 
| -      } | 
| +      Prefs.set(pref, value); | 
| }, | 
| enumerable: true | 
| }); | 
| @@ -332,10 +344,6 @@ | 
| { | 
| for (let key in items) | 
| overrides[keyToPref(key)] = items[key]; | 
| -    }, | 
| -    (error) => | 
| -    { | 
| -      console.error(error); | 
| } | 
| ); | 
|  | 
|  |