FeatureManagement: All features have an associated class on the body tag

This is a common need for features, and having these use a standardized
class name will make using them a lot easier.

Change-Id: I0e16c26878e7d4399d2bf57f236523d214951a27
This commit is contained in:
Jon Robson 2022-09-01 09:58:56 -07:00 committed by Jdlrobson
parent 75115f841c
commit 742f659b10
4 changed files with 38 additions and 4 deletions

View file

@ -126,6 +126,21 @@ final class FeatureManager {
$this->features[$feature] = $requirements; $this->features[$feature] = $requirements;
} }
/**
* Return a list of classes that should be added to the body tag
*
* @return array
*/
public function getFeatureBodyClass() {
$featureManager = $this;
return array_map( static function ( $featureName ) use ( $featureManager ) {
// switch to lower case and switch from camel case to hyphens
$featureClass = ltrim( strtolower( preg_replace( '/[A-Z]([A-Z](?![a-z]))*/', '-$0', $featureName ) ), '-' );
$prefix = 'vector-feature-' . $featureClass . '-';
return $featureManager->isFeatureEnabled( $featureName ) ? $prefix . 'enabled' : $prefix . 'disabled';
}, array_keys( $this->features ) );
}
/** /**
* Gets whether the feature's requirements are met. * Gets whether the feature's requirements are met.
* *

View file

@ -650,9 +650,8 @@ class Hooks implements
} }
$featureManager = VectorServices::getFeatureManager(); $featureManager = VectorServices::getFeatureManager();
if ( $featureManager->isFeatureEnabled( Constants::FEATURE_LANGUAGE_IN_MAIN_PAGE_HEADER ) ) { $bodyAttrs['class'] .= ' ' . implode( ' ', $featureManager->getFeatureBodyClass() );
$bodyAttrs['class'] .= ' vector-language-in-header-enabled'; $bodyAttrs['class'] = trim( $bodyAttrs['class'] );
}
} }
/** /**

View file

@ -2,7 +2,7 @@
@import '../../common/variables.less'; @import '../../common/variables.less';
@import 'mediawiki.mixins.less'; @import 'mediawiki.mixins.less';
// Note vector-language-in-header-enabled class is not used here as that class // Note vector-feature-language-in-header-enabled class is not used here as that class
// only applies to main page. // only applies to main page.
// This must be limited to mw-body-header as the mw-portlet-lang class is shared with // This must be limited to mw-body-header as the mw-portlet-lang class is shared with
// the language portlet that can display in the sidebar. // the language portlet that can display in the sidebar.

View file

@ -61,6 +61,26 @@ class FeatureManagerTest extends \MediaWikiUnitTestCase {
]; ];
} }
/**
* @covers ::getFeatureBodyClass
*/
public function testGetFeatureBodyClass() {
$featureManager = new FeatureManager();
$featureManager->registerSimpleRequirement( 'requirement', true );
$featureManager->registerSimpleRequirement( 'disabled', false );
$featureManager->registerFeature( 'sticky-header', [ 'requirement' ] );
$featureManager->registerFeature( 'TableOfContents', [ 'requirement' ] );
$featureManager->registerFeature( 'Test', [ 'disabled' ] );
$this->assertEquals(
[
'vector-feature-sticky-header-enabled',
'vector-feature-table-of-contents-enabled',
'vector-feature-test-disabled'
],
$featureManager->getFeatureBodyClass()
);
}
/** /**
* @dataProvider provideInvalidFeatureConfig * @dataProvider provideInvalidFeatureConfig
* @covers ::registerFeature * @covers ::registerFeature