Labs/Jetpack/JEP/24

From MozillaWiki
< Labs‎ | Jetpack‎ | JEP
Jump to: navigation, search

JEP 24 - Settings

Introduction

Jetpacks would benefit from a simple way for their users to configure them. Common configuration use cases include minor visual/functional tweaks and account credentials for jetpacks that integrate with services. The basic idea is to make it as easy as possible for jetpacks to provide an interface for users to configure their settings.

We propose an API whereby jetpacks can specify their user-configurable settings, and Jetpack automatically generates a user interface based on the specification. The API will allow jetpacks to specify different types of settings, and the types are interface-agnostic, separating view from control logic such that Jetpack is not bound to a single user-facing representation of any given type, which means that Jetpack can continue to innovate on user interfaces for settings configuration in the future without requiring authors to update their setting specifications.

Settings persist across browser sessions and are stored using the Jetpack storage API. Settings are jetpack-specific and are not accessible by other jetpacks.

API

Accessing Settings

Settings are stored in the jetpack.storage.settings object and are accessible to jetpacks via simple object retrieval and assignment.

If you get a setting that the user hasn't set, but you've specified a default value for the setting, you'll get the default value.

If you access a password setting, and the user has a master password, and they haven't yet entered the master password for the current browsing session, they'll be prompted to enter their master password.

Specifying Settings in a Manifest

To specify its settings, a jetpack includes a top-level manifest object with a settings property whose value is an array of objects representing the setting groups and settings to expose to users. When a user configures the jetpack, Jetpack will generate an interface for doing so based on this specification.

For example, the following code:

var manifest = {
  settings: [
    {
      name: "twitter",
      type: "group",
      label: "Twitter",
      settings: [
        { name: "username", type: "text", label: "Username" },
        { name: "password", type: "password", label: "Password" }
      ]
    },
    {
      name: "facebook",
      type: "group",
      label: "Facebook",
      settings: [
        { name: "username", type: "text", label: "Username", default: "jdoe" },
        { name: "password", type: "password", label: "Secret" }
      ]
    },
    { name: "music", type: "boolean", label: "Music", default: true },
    { name: "volume", type: "range", label: "Volume", min: 0, max: 10, default: 5 }
  ]
};

might result in the following interface:

+ Twitter -------------+
| Username: [        ] |
| Password: [        ] |
+----------------------+

+ Facebook ------------+
| Username: [ jdoe   ] |
| Secret:   [        ] |
+----------------------+

  [x] Music
  Volume: [----|----]

and the following stored properties:

  • jetpack.storage.settings.twitter.username
  • jetpack.storage.settings.twitter.password
  • jetpack.storage.settings.facebook.username
  • jetpack.storage.settings.facebook.password
  • jetpack.storage.settings.music
  • jetpack.storage.settings.volume

Setting Objects

Setting objects have the following properties:

name
The name of the setting. Required. It must be unique within a group of settings for a jetpack. It will be used as a property name in the jetpack.storage.settings object.
type
The kind of values the setting can store. Required.
label
A human-readable descriptive term identifying the setting. Required. It will be displayed in the user interface. Future support for localization of jetpacks might alter the usage or behavior of this property.
default
The default value of the setting. Optional.

Setting Types

While there are numerous potential setting types (think dates, autocomplete fields, multiselect fields, etc.) we'll start with the following restricted set:

group
a group of settings
boolean
a setting that is either true or false
text
a string of characters
number
a number
password
a string that should be treated as a password or other confidential information
range
a number within two bounds
member
a value from a set of possible values

Settings of certain types have additional properties.

group

The group type has the following additional properties:

settings
An array of the setting objects contained by the group. Required.
boolean

The boolean type has the following additional properties:

trueLabel
A human-readable descriptive term identifying the true value. Optional.
falseLabel
A human-readable descriptive term identifying the false value. Optional.
text

The text type has no additional properties.

number

The number type has no additional properties.

password

Values for the password type are stored in Firefox's password manager, although they are accessible as properties on the settings store object. If a user uses a master password, and they haven't entered it yet during the current browsing session, they will be prompted to enter it when a jetpack retrieves a password from the settings store object.

range

The range type has the following additional properties:

min
the minimum value of the setting. Optional. Default value is 0.
max
the maximum value of the setting. Optional. Default value is 100.
step
the discrete amount by which the setting changes. Optional. Default value is 1.
member

The member type has the following additional properties:

set
An array of the possible values. Required.

jetpack.settings.open

Jetpacks can display their setting interface to users by calling jetpack.settings.open().

Access Points

The setting interface will be accessible to users via the following access points:

  • the context menu for a jetpack, which users see when they context-click on its visible UI
  • any element of the jetpack itself that calls jetpack.settings.open
  • an option in the install list:

20090901-fm37j2r5cm3t1tm25eqjtbabrd.jpg

  • embedded in the first-run page (at least linked from the first-run page)?

Future Ideas

  • dependencies
  • callbacks
  • the ability to disable/enable settings
  • input validation
  • a mechanism for jetpacks to modify each others' settings (with permission)
  • putting the specification into a manifest instead of requiring an API call
  • HTML-based settings
  • custom CSS

HTML-based Settings

Any HTML element in a first-run page or in a block of HTML in the settings page that has an class of "setting" will have its value stored in the jetpack's settings. The id is taken as the setting name. Periods are used to indicate heiarchy. For example: id="Twitter.User name" can be accessed via jetpack.storage.settings["Twitter"]["User name"].

Example:

<div>User name: <input type="text" id="twitter.User name" class="setting"></div>

Custom CSS

settings.setup("big.css", {
  "Flavor": ["Chocolate", "Vanilla", "Matcha"], 
  "Color": {value:["Red", "Greed", "Mauve"], class="big"},
  "Name": {type:"text", style:"font-weight:bold;"}
});

Which injects big.css into the HTML representation of the settings (as well as the inline-styles).

If you want to define your own HTML for a settings page:

settings.setup("mysettings.html");

Then you just have HTML with appropriately id's and class's names (see below).