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 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 (HTML) may or may not be up to date but the JS and CSS will be. The feature management system will handle this by updating the state of the application to reflect that the feature is disabled.
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 installed. function canBeEnabled( $context ); // Per T141087#2518683: should the feature indicate that the feature is enabled/disabled in CSS, // i.e. should it add feature-foo or no-feature-foo CSS classes (respectively) to body element. function shouldEnableInCss(); // Get the feature-specific hooks that should be registered. function getHooks(); }
{ 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 ) {}; // Per T141087#2501334: a recurring pattern in the MobileFrontend codebase is to load a set of // modules and then bootstrap a feature. whenLoaded( feature ); }
- the feature manager will add classes to the html 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 discrepancy 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
- Organise the MobileFrontend codebase into a core and a set of features
Potential proposal
- Add a feature manager class to the PHP codebase
- Provide a single mechanism to register features, e.g. $wgMFFeatures config var
- Add classes to the body element for the CSS code to target
- Forward additional state to the client (via mw.config presumably)
- Add a feature manager class to the JS codebase
- Hydrate the state of the JS feature manager from the forwarded state (from mw.config presumably)
- Identify 5 features that can be migrated to basic feature management
- Migrate the features
- Due to caching, it's likely that there'll be discrepancies between the two different representations of the feature manager state, the classes added to the body element and the mw.config, when a feature is enabled or disabled on the backend. The client-side feature manager should detect this discrepancy.
- Add Special:MobileFeatures special page which:
- lists all registered features;
- lists features enabled in MFBeta; and
- lists enabled enabled in MFStable (and MFBeta)
- Email mobile-l about the migration