.. _components/featuregates: ============= Feature Gates ============= A feature gate is a high level tool to turn features on and off. It provides metadata about features, a simple, opinionated API, and avoid many potential pitfalls of other systems, such as using preferences directly. It is designed to be compatible with tools that want to know and affect the state of features in Firefox over time and in the wild. Feature Definitions =================== All features must have a definition, specified in ``toolkit/components/featuregates/Features.toml``. These definitions include data such as references to title and description strings (to be shown to users), and bug numbers (to track the development of the feature over time). Here is an example feature definition with an id of ``demo-feature``: .. code-block:: toml [demo-feature] title = "experimental-features-demo-feature" description = "experimental-features-demo-feature-description" restart-required = false bug-numbers = [1479127] type = "boolean" is-public = {default = false, nightly = true} default-value = {default = false, nightly = true} The references defined in the `title` and `description` values point to strings stored in ``toolkit/locales/en-US/toolkit/featuregates/features.ftl``. The `title` string should specify the user-facing string as the `label` attribute. .. _targeted value: Targeted values --------------- Several fields can take a value that indicates it varies by channel and OS. These are known as *targeted values*. The simplest computed value is to simply provide the value: .. code-block:: toml default-value = true A more interesting example is to make a feature default to true on Nightly, but be disabled otherwise. That would look like this: .. code-block:: toml default-value = {default = false, nightly = true} Values can depend on multiple conditions. For example, to enable a feature only on Nightly running on Windows: .. code-block:: toml default-value = {default = false, "nightly,win" = true} Multiple sets of conditions can be specified, however use caution here: if multiple sets could match (except ``default``), the set chosen is undefined. An example of safely using multiple conditions: .. code-block:: toml default-value = {default = false, nightly = true, "beta,win" = true} The ``default`` condition is required. It is used as a fallback in case no more-specific case matches. The conditions allowed are * ``default`` * ``release`` * ``beta`` * ``dev-edition`` * ``nightly`` * ``esr`` * ``win`` * ``mac`` * ``linux`` * ``android`` Fields ------ title Required. The string ID of the human readable name for the feature, meant to be shown to users. Should fit onto a single line. The actual string should be defined in ``toolkit/locales/en-US/toolkit/featuregates/features.ftl`` with the user-facing value defined as the `label` attribute of the string. description Required. The string ID of the human readable description for the feature, meant to be shown to users. Should be at most a paragraph. The actual string should be defined in ``toolkit/locales/en-US/toolkit/featuregates/features.ftl``. description-links Optional. A dictionary of key-value pairs that are referenced in the description. The key name must appear in the description localization text as . For example in Features.toml: .. code-block:: toml [demo-feature] title = "experimental-features-demo-feature" description = "experimental-features-demo-feature-description" description-links = {exampleCom = "https://example.com", exampleOrg = "https://example.org"} restart-required = false bug-numbers = [1479127] type = "boolean" is-public = {default = false, nightly = true} default-value = {default = false, nightly = true} and in features.ftl: .. code-block:: fluent experimental-features-demo-feature = .label = Example Demo Feature experimental-features-demo-feature-description = Example demo feature that can point to .com links and .org links. bug-numbers Required. A list of bug numbers related to this feature. This should likely be the metabug for the the feature, but any related bugs can be included. At least one bug is required. restart-required Required. If this feature requires a the browser to be restarted for changes to take effect, this field should be ``true``. Otherwise, the field should be ``false``. Features should aspire to not require restarts and react to changes to the preference dynamically. type Required. The type of value this feature relates to. The only legal value is ``boolean``, but more may be added in the future. preference Optional. The preference used to track the feature. If a preference is not provided, one will be automatically generated based on the feature ID. It is not recommended to specify a preference directly, except to integrate with older code. In the future, alternate storage mechanisms may be used if a preference is not supplied. default-value Optional. This is a `targeted value`_ describing the value for the feature if no other changes have been made, such as in a fresh profile. If not provided, the default for a boolean type feature gate will be ``false`` for all profiles. is-public Optional. This is a `targeted value`_ describing on which branches this feature should be exposed to users. When a feature is made public, it may show up in a future UI that allows users to opt-in to experimental features. This is not related to ``about:preferences`` or ``about:config``. If not provided, the default is to make a feature private for all channels. Feature Gate API ================ .. (comment) The below lists should be kept in sync with the contents of the classes they are documenting. An explicit list is used so that the methods can be put in a particular order. .. js:autoclass:: FeatureGate :members: addObserver, removeObserver, isEnabled, fromId .. js:autoclass:: FeatureGateImplementation :members: id, title, description, type, bugNumbers, isPublic, defaultValue, restartRequired, preference, addObserver, removeObserver, removeAllObservers, getValue, isEnabled Feature implementors should use the methods :func:`fromId`, :func:`addListener`, :func:`removeListener` and :func:`removeAllListeners`. Additionally, metadata is available for UI and analysis.