Skip to content

Configuration library for Firefox addons based on WebExtensions

License

Notifications You must be signed in to change notification settings

piroor/webextensions-lib-configs

Repository files navigation

webextensions-lib-configs

Build Status

Provides ability to store/load configurations, on Firefox 52 and later.

By the bug 1197346, now we don't have to do inter-sandboxes comunication to read/write configuration values. After the bug, this library is still effective to provide easy access for configuration values.

Required permissions

  • storage

Usage

In manifest.json, load the file Configs.js from both the background page and others, like:

{
  "background": {
    "scripts": [
      "path/to/Configs.js",
      "path/to/common.js"
    ]
  },
  "content_scripts": [
    {
      "all_frames": true,
      "matches": [
        "<all_urls>"
      ],
      "js": [
        "path/to/Configs.js",
        "path/to/common.js",
        "..."
      ],
      "run_at": "document_start"
    }
  ],
  "options_ui": {
    "page": "path/to/options.html",
    "chrome_style": true
  },
  "permissions": [
    "storage"
  ]
}

options.html is:

<!DOCTYPE html>
<script type="application/javascript" src="./Configs.js"></script>
<script type="application/javascript" src="./common.js"></script>
...

And, define an instance with default values on each namespace like:

// common.js

var configs = new Configs({
  enabled: true,
  advanced: false,
  attributes: 'alt|title',
  entries: [],
  cache: {}
});

The instance has a built-in property $loaded. It is a Promise, so you can do something after all stored user values are loaded:

configs.$loaded.then(function() {
  MyService.start();
});

After all values are loaded, you can access loaded values via its own properties same to the given default values:

console.log(configs.enabled); // => true (default value)
console.log(configs.advanced); // => false (default value)
console.log(configs.attributes); // => "alt|title" (default value)
console.log(configs.cache); // => {} (default value)

If you set a new value, it will be notified to the background page, then stored to the local storage as the user value and dispatched to all other namespaces.

// in the options.html
configs.enabled = false;
// in content script
console.log(configs.enabled); // => false (user value)

You still can get default values easily, with a prefix $default.:

console.log(configs.$default.enabled); // => true (default value)
configs.enabled = configs.$default.enabled; // reset to default

configs.$reset(); // reset all to default

Important note around object or array values

When you hope to update a non-primitive configuration values, note that you must replace the object itself. For example, deep clone based on JSON.parse() and JSON.stringify() will be effective:

var newEntries = JSON.parse(JSON.stringify(configs.entries)); // deep clone
entries.push('added item');
configs.entries = newEntries;

var newCache = JSON.parse(JSON.stringify(configs.cache)); // deep clone
newCache.addedItem = true;
configs.cache = newCache;

In other words, following codes don't work as expected:

// Directly modified object won't be saved.
configs.entries.push('added item');
configs.cache.addedItems = true;

// Simple assignment also uses the object itself,
// so this example is same to the previous.
{
   let newEntries = configs.entries;
   newEntries.push('added item');
   configs.entries = newEntries;

   let newCache = configs.cache;
   newCache.addedItems = true;
   configs.cache = newCache;
}

// Shallow clone is better than above, and it works as expected
// only when all values are primitive.
{
   let newEntries = configs.entries.slice(0);
   newEntries.push('added item');
   configs.entries = newEntries;

   let newCache = { ...configs.cache }; // shallow clone
   newCache.addedItems = true;
   configs.cache = newCache;
}

Managed Storage

This library supports storage.managed. Configuration items which have any value in storage.managed are treated as locked configuration and they become unchangable. For more details, see the API documentation.

For providing default configs instead of completely managed locked configs, please use :unlock suffix for each key. If you define :unlocked-suffixed key with false value, the corresponding config will become unlocked, for example:

{
  "name": "...",
  "description": "...",
  "type": "storage",
  "data":
  {
    "color": "#FF0000",
    "color:locked", false // <= HERE! This makes "color" unlocked.
  }
}

Sync Storage

This library supports storage.sync. To use it, set syncKeys in the optional second parameter of the Configs constructor to an array of the key names that should be synced:

var configs = new Configs({
  enabled: true,
  advanced: false,
  attributes: 'alt|title'
}, {
  syncKeys: ['enabled', 'attributes']
});

Alternately, specify (possibly empty) array of keys which should not be synced in localKeys:

var configs = new Configs({
  enabled: true,
  advanced: false,
  attributes: 'alt|title'
}, {
  localKeys: ['advanced']
});

About

Configuration library for Firefox addons based on WebExtensions

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages