== What? ==
The MobileFrontend ~~extension~~ application comprises of a set of core modules and a set of features that rely on them. Some-to-most of these features can be enabled or disabled by setting a configuration variable, a **flag**, to a truthy value. Moreover, most of these features also have additional configuration variables, which change the behaviour of specific parts of the feature.
[The number of features in the application is large](https://www.mediawiki.org/wiki/Reading/Features#Feature_matrix) and their configuration and location in the codebase sufficiently complex that it's non-trivial to identify and document them after the fact. A feature management system for MobileFrontend, therefore, must not only standardise how a feature is enabled and configured, but also where it's defined and documented as well. Moreover, this information should be immediately available to both MobileFrontend developers and to stakeholders, e.g. the Product Owner of the Reading Web team, and users.
A feature's behaviour can be implemented in PHP and/or JS, and CSS – LESS strictly. Consequently, the feature management system must make information about the feature available in those execution environments. A rough feature flagging system emerged in MobileFrontend's RL modules definitions, wherein modules added as dependencies of `skins.minerva.scripts` and `skins.minerva.beta.scripts` were "enabled" features, i.e. that their modules would be loaded by the client. By including the set of RL modules to load in a feature's definition, the feature management system can allow developers to concentrate on features rather than unnecessarily complex RL module hierarchies.
MobileFrontend can operate in either "stable" or "beta" mode. Generally speaking, all features are expected to be enabled in beta mode and will, at some point, be "promoted" from beta to stable mode. Given that the majority of requests to the Wikipedias are serviced by Varnish, promoting a feature requires considering how the distinct parts of the feature's implementation will interact when the feature is enabled, i.e. the response from Varnish may or may not be up to date but the JS and CSS will be. The feature management system must provide a mechanism for handling this state gracefully by either:
* updating the state of the application to reflect that the feature is disabled, which should probably be the default behaviour; or
* allowing a feature to provide a script – say, an RL module – that'll update the state of the application such that the feature can be enabled
== How? ==
* in both PHP and JS, the feature manager will allow a client to query whether a feature is enabled or disabled, e.g.
```
interface FeatureManager {
function isFeatureEnabled( $feature, $context );
function isFeatureDisabled( $feature, $context );
function getEnabledFeatures();
}
```
```
interface Feature {
function getName();
function getResourceLoaderModules();
// Allow a feature to determine whether or not it //can// be enabled, e.g. the notifications
// feature requires the Echo extension to be intalled.
function canBeEnabled( $context );
}
```
```
{
isFeatureEnabled: function ( feature, context ) {},
isFeatureDisabled: function ( feature, context ) {},
// JavaScript-specific use cases: the MobileFrontend application often defers loading of RL
// modules - a feature's implementation - until the user has interacted with the page.
loadFeature: function ( feature } {},
loadFeatures: function ( features ) {}
}
```
* the feature manager will add classes to the `html` – or `body` – element of the DOM if a feature is enabled or disabled, e.g. `language-switcher` and `no-language-switcher` respectively
** these classes will be added in PHP and delivered as part of the initial response
** if the feature manager detects a discrepency in the JS state and these classes, then it must handle it as discussed above
* a Special:MobileFeatures special page will output the state of the feature manager for stakeholders and users
==Why==
* Provide a consistent way to query features regardless of cached HTML or not.
* Avoid intermediate patches to get features ready for deployment to stable (removing beta checks, swapping them with other things, etc)
* Provide consistent explicit feature flagging in CSS (which we don't have)
* Provide a place to show which features are enabled, and which are not, per wiki