From 742f659b10e814179d8869624a37839800996af5 Mon Sep 17 00:00:00 2001 From: Jon Robson Date: Thu, 1 Sep 2022 09:58:56 -0700 Subject: [PATCH] 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 --- includes/FeatureManagement/FeatureManager.php | 15 ++++++++++++++ includes/Hooks.php | 5 ++--- .../components/LanguageButton.less | 2 +- .../FeatureManagement/FeatureManagerTest.php | 20 +++++++++++++++++++ 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/includes/FeatureManagement/FeatureManager.php b/includes/FeatureManagement/FeatureManager.php index cbcb508c..497fbeef 100644 --- a/includes/FeatureManagement/FeatureManager.php +++ b/includes/FeatureManagement/FeatureManager.php @@ -126,6 +126,21 @@ final class FeatureManager { $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. * diff --git a/includes/Hooks.php b/includes/Hooks.php index 32b51853..1e3db76c 100644 --- a/includes/Hooks.php +++ b/includes/Hooks.php @@ -650,9 +650,8 @@ class Hooks implements } $featureManager = VectorServices::getFeatureManager(); - if ( $featureManager->isFeatureEnabled( Constants::FEATURE_LANGUAGE_IN_MAIN_PAGE_HEADER ) ) { - $bodyAttrs['class'] .= ' vector-language-in-header-enabled'; - } + $bodyAttrs['class'] .= ' ' . implode( ' ', $featureManager->getFeatureBodyClass() ); + $bodyAttrs['class'] = trim( $bodyAttrs['class'] ); } /** diff --git a/resources/skins.vector.styles/components/LanguageButton.less b/resources/skins.vector.styles/components/LanguageButton.less index cd03a03f..c2234c32 100644 --- a/resources/skins.vector.styles/components/LanguageButton.less +++ b/resources/skins.vector.styles/components/LanguageButton.less @@ -2,7 +2,7 @@ @import '../../common/variables.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. // 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. diff --git a/tests/phpunit/unit/FeatureManagement/FeatureManagerTest.php b/tests/phpunit/unit/FeatureManagement/FeatureManagerTest.php index 73de2fe2..5f7309ee 100644 --- a/tests/phpunit/unit/FeatureManagement/FeatureManagerTest.php +++ b/tests/phpunit/unit/FeatureManagement/FeatureManagerTest.php @@ -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 * @covers ::registerFeature