diff --git a/includes/Components/VectorComponentStickyHeader.php b/includes/Components/VectorComponentStickyHeader.php index 351227b37..428f88ad3 100644 --- a/includes/Components/VectorComponentStickyHeader.php +++ b/includes/Components/VectorComponentStickyHeader.php @@ -1,22 +1,134 @@ '#', + 'id' => 'ca-talk-sticky-header', + 'event' => 'talk-sticky-header', + 'icon' => 'wikimedia-speechBubbles', + 'is-quiet' => true, + 'tabindex' => '-1', + 'class' => 'sticky-header-icon' + ]; + private const SUBJECT_ICON = [ + 'href' => '#', + 'id' => 'ca-subject-sticky-header', + 'event' => 'subject-sticky-header', + 'icon' => 'wikimedia-article', + 'is-quiet' => true, + 'tabindex' => '-1', + 'class' => 'sticky-header-icon' + ]; + private const HISTORY_ICON = [ + 'href' => '#', + 'id' => 'ca-history-sticky-header', + 'event' => 'history-sticky-header', + 'icon' => 'wikimedia-history', + 'is-quiet' => true, + 'tabindex' => '-1', + 'class' => 'sticky-header-icon' + ]; + // Event and icon will be updated depending on watchstar state + private const WATCHSTAR_ICON = [ + 'href' => '#', + 'id' => 'ca-watchstar-sticky-header', + 'event' => 'watch-sticky-header', + 'icon' => 'wikimedia-star', + 'is-quiet' => true, + 'tabindex' => '-1', + 'class' => 'sticky-header-icon mw-watchlink' + ]; + private const EDIT_VE_ICON = [ + 'href' => '#', + 'id' => 'ca-ve-edit-sticky-header', + 'event' => 've-edit-sticky-header', + 'icon' => 'wikimedia-edit', + 'is-quiet' => true, + 'tabindex' => '-1', + 'class' => 'sticky-header-icon' + ]; + private const EDIT_WIKITEXT_ICON = [ + 'href' => '#', + 'id' => 'ca-edit-sticky-header', + 'event' => 'wikitext-edit-sticky-header', + 'icon' => 'wikimedia-wikiText', + 'is-quiet' => true, + 'tabindex' => '-1', + 'class' => 'sticky-header-icon' + ]; + private const EDIT_PROTECTED_ICON = [ + 'href' => '#', + 'id' => 'ca-viewsource-sticky-header', + 'event' => 've-edit-protected-sticky-header', + 'icon' => 'wikimedia-editLock', + 'is-quiet' => true, + 'tabindex' => '-1', + 'class' => 'sticky-header-icon' + ]; + /** @var MessageLocalizer */ private $localizer; + /** @var VectorComponent */ + private $toc; + /** @var VectorComponent */ + private $search; + /** @var VectorComponent|null */ + private $langButton; + /** @var bool */ + private $includeEditIcons; /** * @param MessageLocalizer $localizer + * @param VectorComponent $searchBox + * @param VectorComponent|null $langButton + * @param bool $includeEditIcons whether to include edit icons in the result */ - public function __construct( MessageLocalizer $localizer ) { + public function __construct( + MessageLocalizer $localizer, + VectorComponent $searchBox, + $langButton = null, + $includeEditIcons = false + ) { + $this->search = $searchBox; + $this->langButton = $langButton; + $this->includeEditIcons = $includeEditIcons; $this->localizer = $localizer; } + /** + * @param mixed $key + * @return Message + */ + private function msg( $key ): Message { + return $this->localizer->msg( $key ); + } + + /** + * Creates button data for the "Add section" button in the sticky header + * + * @return array + */ + private function getAddSectionButtonData() { + return [ + 'href' => '#', + 'id' => 'ca-addsection-sticky-header', + 'event' => 'addsection-sticky-header', + 'html-vector-button-icon' => Hooks::makeIcon( 'wikimedia-speechBubbleAdd-progressive' ), + 'label' => $this->msg( [ 'vector-2022-action-addsection', 'skin-action-addsection' ] )->text(), + 'is-quiet' => true, + 'tabindex' => '-1', + 'class' => 'sticky-header-icon mw-ui-primary mw-ui-progressive' + ]; + } + /** * @inheritDoc */ @@ -31,9 +143,35 @@ class VectorComponentStickyHeader implements VectorComponent { 'mw-portlet mw-portlet-sticky-header-toc vector-sticky-header-toc', 'listBullet' ); + $btns = [ + self::TALK_ICON, + self::SUBJECT_ICON, + self::HISTORY_ICON, + self::WATCHSTAR_ICON, + ]; + if ( $this->includeEditIcons ) { + $btns[] = self::EDIT_WIKITEXT_ICON; + $btns[] = self::EDIT_PROTECTED_ICON; + $btns[] = self::EDIT_VE_ICON; + } + $btns[] = $this->getAddSectionButtonData(); + $searchBoxData = $this->search->getTemplateData(); + return [ 'data-sticky-header-toc-pinnable-container' => $pinnableContainer->getTemplateData(), 'data-sticky-header-toc-dropdown' => $tocDropdown->getTemplateData(), + 'data-buttons' => $btns, + 'data-primary-action' => $this->langButton ? + $this->langButton->getTemplateData() : null, + 'data-button-start' => [ + 'label' => $this->msg( 'search' ), + 'icon' => 'wikimedia-search', + 'is-quiet' => true, + 'tabindex' => '-1', + 'class' => 'vector-sticky-header-search-toggle', + 'event' => 'ui.' . $searchBoxData['form-id'] . '.icon' + ], + 'data-search' => $searchBoxData, ]; } } diff --git a/includes/SkinVector.php b/includes/SkinVector.php deleted file mode 100644 index ca3c6029e..000000000 --- a/includes/SkinVector.php +++ /dev/null @@ -1,306 +0,0 @@ - '#', - 'id' => 'ca-talk-sticky-header', - 'event' => 'talk-sticky-header', - 'icon' => 'wikimedia-speechBubbles', - 'is-quiet' => true, - 'tabindex' => '-1', - 'class' => 'sticky-header-icon' - ]; - private const SUBJECT_ICON = [ - 'href' => '#', - 'id' => 'ca-subject-sticky-header', - 'event' => 'subject-sticky-header', - 'icon' => 'wikimedia-article', - 'is-quiet' => true, - 'tabindex' => '-1', - 'class' => 'sticky-header-icon' - ]; - private const HISTORY_ICON = [ - 'href' => '#', - 'id' => 'ca-history-sticky-header', - 'event' => 'history-sticky-header', - 'icon' => 'wikimedia-history', - 'is-quiet' => true, - 'tabindex' => '-1', - 'class' => 'sticky-header-icon' - ]; - // Event and icon will be updated depending on watchstar state - private const WATCHSTAR_ICON = [ - 'href' => '#', - 'id' => 'ca-watchstar-sticky-header', - 'event' => 'watch-sticky-header', - 'icon' => 'wikimedia-star', - 'is-quiet' => true, - 'tabindex' => '-1', - 'class' => 'sticky-header-icon mw-watchlink' - ]; - private const EDIT_VE_ICON = [ - 'href' => '#', - 'id' => 'ca-ve-edit-sticky-header', - 'event' => 've-edit-sticky-header', - 'icon' => 'wikimedia-edit', - 'is-quiet' => true, - 'tabindex' => '-1', - 'class' => 'sticky-header-icon' - ]; - private const EDIT_WIKITEXT_ICON = [ - 'href' => '#', - 'id' => 'ca-edit-sticky-header', - 'event' => 'wikitext-edit-sticky-header', - 'icon' => 'wikimedia-wikiText', - 'is-quiet' => true, - 'tabindex' => '-1', - 'class' => 'sticky-header-icon' - ]; - private const EDIT_PROTECTED_ICON = [ - 'href' => '#', - 'id' => 'ca-viewsource-sticky-header', - 'event' => 've-edit-protected-sticky-header', - 'icon' => 'wikimedia-editLock', - 'is-quiet' => true, - 'tabindex' => '-1', - 'class' => 'sticky-header-icon' - ]; - - /** - * Calls getLanguages with caching. - * @return array - */ - protected function getLanguagesCached(): array { - if ( $this->languages === null ) { - $this->languages = $this->getLanguages(); - } - return $this->languages; - } - - /** - * This should be upstreamed to the Skin class in core once the logic is finalized. - * Returns false if the page is a special page without any languages, or if an action - * other than view is being used. - * @return bool - */ - private function canHaveLanguages(): bool { - if ( $this->getContext()->getActionName() !== 'view' ) { - return false; - } - $title = $this->getTitle(); - // Defensive programming - if a special page has added languages explicitly, best to show it. - if ( $title && $title->isSpecialPage() && empty( $this->getLanguagesCached() ) ) { - return false; - } - return true; - } - - /** - * @param string $location Either 'top' or 'bottom' is accepted. - * @return bool - */ - protected function isLanguagesInContentAt( $location ) { - if ( !$this->canHaveLanguages() ) { - return false; - } - $featureManager = VectorServices::getFeatureManager(); - $inContent = $featureManager->isFeatureEnabled( - Constants::FEATURE_LANGUAGE_IN_HEADER - ); - $isMainPage = $this->getTitle() ? $this->getTitle()->isMainPage() : false; - - switch ( $location ) { - case 'top': - return $isMainPage ? $inContent && $featureManager->isFeatureEnabled( - Constants::FEATURE_LANGUAGE_IN_MAIN_PAGE_HEADER - ) : $inContent; - case 'bottom': - return $inContent && $isMainPage && !$featureManager->isFeatureEnabled( - Constants::FEATURE_LANGUAGE_IN_MAIN_PAGE_HEADER - ); - default: - throw new RuntimeException( 'unknown language button location' ); - } - } - - /** - * Whether or not the languages are out of the sidebar and in the content either at - * the top or the bottom. - * @return bool - */ - final protected function isLanguagesInContent() { - return $this->isLanguagesInContentAt( 'top' ) || $this->isLanguagesInContentAt( 'bottom' ); - } - - /** - * Whether languages should be hidden. - * FIXME: Function should be removed as part of T319355 - * - * @return bool - */ - abstract protected function shouldHideLanguages(): bool; - - /** - * @inheritDoc - */ - protected function runOnSkinTemplateNavigationHooks( SkinTemplate $skin, &$content_navigation ) { - parent::runOnSkinTemplateNavigationHooks( $skin, $content_navigation ); - Hooks::onSkinTemplateNavigation( $skin, $content_navigation ); - } - - /** - * Check whether ULS is enabled - * - * @return bool - */ - final protected function isULSExtensionEnabled(): bool { - return ExtensionRegistry::getInstance()->isLoaded( 'UniversalLanguageSelector' ); - } - - /** - * Generate data needed to generate the sticky header. - * FIXME: Move to VectorComponentStickyHeader - * @param array $searchBoxData - * @param bool $includeEditIcons - * @return array - */ - final protected function getStickyHeaderData( $searchBoxData, $includeEditIcons ): array { - $btns = [ - self::TALK_ICON, - self::SUBJECT_ICON, - self::HISTORY_ICON, - self::WATCHSTAR_ICON, - ]; - if ( $includeEditIcons ) { - $btns[] = self::EDIT_WIKITEXT_ICON; - $btns[] = self::EDIT_PROTECTED_ICON; - $btns[] = self::EDIT_VE_ICON; - } - $btns[] = $this->getAddSectionButtonData(); - - // Show sticky ULS if the ULS extension is enabled and the ULS in header is not hidden - $showStickyULS = $this->isULSExtensionEnabled() && !$this->shouldHideLanguages(); - $langButton = new VectorComponentLanguageButton( $this->getULSLabels()[ 'label' ] ); - - return [ - 'data-primary-action' => $showStickyULS ? - $langButton->getTemplateData() : null, - 'data-button-start' => [ - 'label' => $this->msg( 'search' ), - 'icon' => 'wikimedia-search', - 'is-quiet' => true, - 'tabindex' => '-1', - 'class' => 'vector-sticky-header-search-toggle', - 'event' => 'ui.' . $searchBoxData['form-id'] . '.icon' - ], - 'data-search' => $searchBoxData, - 'data-buttons' => $btns, - ]; - } - - /** - * @inheritDoc - */ - public function isResponsive() { - // Check it's enabled by user preference and configuration - $responsive = parent::isResponsive() && $this->getConfig()->get( 'VectorResponsive' ); - // For historic reasons, the viewport is added when Vector is loaded on the mobile - // domain. This is only possible for 3rd parties or by useskin parameter as there is - // no preference for changing mobile skin. Only need to check if $responsive is falsey. - if ( !$responsive && ExtensionRegistry::getInstance()->isLoaded( 'MobileFrontend' ) ) { - $mobFrontContext = MediaWikiServices::getInstance()->getService( 'MobileFrontend.Context' ); - if ( $mobFrontContext->shouldDisplayMobileView() ) { - return true; - } - } - return $responsive; - } - - /** - * Get the ULS button label, accounting for the number of available - * languages. - * - * @return array - */ - final protected function getULSLabels(): array { - $numLanguages = count( $this->getLanguagesCached() ); - - if ( $numLanguages === 0 ) { - return [ - 'label' => $this->msg( 'vector-no-language-button-label' )->text(), - 'aria-label' => $this->msg( 'vector-no-language-button-aria-label' )->text() - ]; - } else { - return [ - 'label' => $this->msg( 'vector-language-button-label' )->numParams( $numLanguages )->escaped(), - 'aria-label' => $this->msg( 'vector-language-button-aria-label' )->numParams( $numLanguages )->escaped() - ]; - } - } - - /** - * Creates button data for the "Add section" button in the sticky header - * - * @return array - */ - private function getAddSectionButtonData() { - return [ - 'href' => '#', - 'id' => 'ca-addsection-sticky-header', - 'event' => 'addsection-sticky-header', - 'html-vector-button-icon' => Hooks::makeIcon( 'wikimedia-speechBubbleAdd-progressive' ), - 'label' => $this->msg( [ 'vector-2022-action-addsection', 'skin-action-addsection' ] ), - 'is-quiet' => true, - 'tabindex' => '-1', - 'class' => 'sticky-header-icon mw-ui-primary mw-ui-progressive' - ]; - } -} diff --git a/includes/SkinVector22.php b/includes/SkinVector22.php index 5fb593c13..611dcdba0 100644 --- a/includes/SkinVector22.php +++ b/includes/SkinVector22.php @@ -2,9 +2,11 @@ namespace MediaWiki\Skins\Vector; +use ExtensionRegistry; use MediaWiki\MediaWikiServices; use MediaWiki\Skins\Vector\Components\VectorComponentDropdown; use MediaWiki\Skins\Vector\Components\VectorComponentIconLink; +use MediaWiki\Skins\Vector\Components\VectorComponentLanguageButton; use MediaWiki\Skins\Vector\Components\VectorComponentLanguageDropdown; use MediaWiki\Skins\Vector\Components\VectorComponentMainMenu; use MediaWiki\Skins\Vector\Components\VectorComponentMenu; @@ -17,14 +19,120 @@ use MediaWiki\Skins\Vector\Components\VectorComponentStickyHeader; use MediaWiki\Skins\Vector\Components\VectorComponentTableOfContents; use MediaWiki\Skins\Vector\Components\VectorComponentTableOfContentsContainer; use MediaWiki\Skins\Vector\Components\VectorComponentUserLinks; +use RuntimeException; +use SkinMustache; +use SkinTemplate; /** * @ingroup Skins * @package Vector * @internal */ -class SkinVector22 extends SkinVector { +class SkinVector22 extends SkinMustache { private const STICKY_HEADER_ENABLED_CLASS = 'vector-sticky-header-enabled'; + /** @var null|array for caching purposes */ + private $languages; + + /** + * @inheritDoc + */ + protected function runOnSkinTemplateNavigationHooks( SkinTemplate $skin, &$content_navigation ) { + parent::runOnSkinTemplateNavigationHooks( $skin, $content_navigation ); + Hooks::onSkinTemplateNavigation( $skin, $content_navigation ); + } + + /** + * @inheritDoc + */ + public function isResponsive() { + // Check it's enabled by user preference and configuration + $responsive = parent::isResponsive() && $this->getConfig()->get( 'VectorResponsive' ); + // For historic reasons, the viewport is added when Vector is loaded on the mobile + // domain. This is only possible for 3rd parties or by useskin parameter as there is + // no preference for changing mobile skin. Only need to check if $responsive is falsey. + if ( !$responsive && ExtensionRegistry::getInstance()->isLoaded( 'MobileFrontend' ) ) { + $mobFrontContext = MediaWikiServices::getInstance()->getService( 'MobileFrontend.Context' ); + if ( $mobFrontContext->shouldDisplayMobileView() ) { + return true; + } + } + return $responsive; + } + + /** + * This should be upstreamed to the Skin class in core once the logic is finalized. + * Returns false if the page is a special page without any languages, or if an action + * other than view is being used. + * @return bool + */ + private function canHaveLanguages(): bool { + if ( $this->getContext()->getActionName() !== 'view' ) { + return false; + } + $title = $this->getTitle(); + // Defensive programming - if a special page has added languages explicitly, best to show it. + if ( $title && $title->isSpecialPage() && empty( $this->getLanguagesCached() ) ) { + return false; + } + return true; + } + + /** + * @param string $location Either 'top' or 'bottom' is accepted. + * @return bool + */ + protected function isLanguagesInContentAt( $location ) { + if ( !$this->canHaveLanguages() ) { + return false; + } + $featureManager = VectorServices::getFeatureManager(); + $inContent = $featureManager->isFeatureEnabled( + Constants::FEATURE_LANGUAGE_IN_HEADER + ); + $isMainPage = $this->getTitle() ? $this->getTitle()->isMainPage() : false; + + switch ( $location ) { + case 'top': + return $isMainPage ? $inContent && $featureManager->isFeatureEnabled( + Constants::FEATURE_LANGUAGE_IN_MAIN_PAGE_HEADER + ) : $inContent; + case 'bottom': + return $inContent && $isMainPage && !$featureManager->isFeatureEnabled( + Constants::FEATURE_LANGUAGE_IN_MAIN_PAGE_HEADER + ); + default: + throw new RuntimeException( 'unknown language button location' ); + } + } + + /** + * Whether or not the languages are out of the sidebar and in the content either at + * the top or the bottom. + * @return bool + */ + final protected function isLanguagesInContent() { + return $this->isLanguagesInContentAt( 'top' ) || $this->isLanguagesInContentAt( 'bottom' ); + } + + /** + * Calls getLanguages with caching. + * @return array + */ + protected function getLanguagesCached(): array { + if ( $this->languages === null ) { + $this->languages = $this->getLanguages(); + } + return $this->languages; + } + + /** + * Check whether ULS is enabled + * + * @return bool + */ + final protected function isULSExtensionEnabled(): bool { + return ExtensionRegistry::getInstance()->isLoaded( 'UniversalLanguageSelector' ); + } /** * Show the ULS button if it's modern Vector, languages in header is enabled, @@ -149,6 +257,28 @@ class SkinVector22 extends SkinVector { } } + /** + * Get the ULS button label, accounting for the number of available + * languages. + * + * @return array + */ + final protected function getULSLabels(): array { + $numLanguages = count( $this->getLanguagesCached() ); + + if ( $numLanguages === 0 ) { + return [ + 'label' => $this->msg( 'vector-no-language-button-label' )->text(), + 'aria-label' => $this->msg( 'vector-no-language-button-aria-label' )->text() + ]; + } else { + return [ + 'label' => $this->msg( 'vector-language-button-label' )->numParams( $numLanguages )->escaped(), + 'aria-label' => $this->msg( 'vector-language-button-aria-label' )->numParams( $numLanguages )->escaped() + ]; + } + } + /** * @return array */ @@ -156,7 +286,6 @@ class SkinVector22 extends SkinVector { $featureManager = VectorServices::getFeatureManager(); $parentData = parent::getTemplateData(); $localizer = $this->getContext(); - $stickyHeader = new VectorComponentStickyHeader( $localizer ); $parentData = $this->mergeViewOverflowIntoActions( $parentData ); $portlets = $parentData['data-portlets']; @@ -177,6 +306,7 @@ class SkinVector22 extends SkinVector { $logoutData = $this->buildLogoutLinkData(); $loginLinkData = $this->buildLoginData( $returnto, $this->useCombinedLoginLink() ); $createAccountData = $this->buildCreateAccountData( $returnto ); + $localizer = $this->getContext(); $components = [ 'data-vector-variants' => new VectorComponentMenuVariants( $parentData['data-portlets']['data-variants'], @@ -184,7 +314,7 @@ class SkinVector22 extends SkinVector { $this->msg( 'vector-language-variant-switcher-label' ) ), 'data-vector-user-links' => new VectorComponentUserLinks( - $this->getContext(), + $localizer, $user, new VectorComponentMenu( $portlets['data-user-menu'] @@ -259,13 +389,13 @@ class SkinVector22 extends SkinVector { true, $config, Constants::SEARCH_BOX_INPUT_LOCATION_MOVED, - $this->getContext() + $localizer ), 'data-main-menu' => new VectorComponentMainMenu( $sidebar, $this->shouldLanguageAlertBeInSidebar(), $parentData['data-portlets']['data-languages'] ?? [], - $this->getContext(), + $localizer, $this->getUser(), VectorServices::getFeatureManager(), $this, @@ -278,7 +408,7 @@ class SkinVector22 extends SkinVector { ), 'data-page-tools' => $isPageToolsEnabled ? new VectorComponentPageTools( array_merge( [ $parentData['data-portlets']['data-actions'] ?? [] ], $pageToolsMenu ), - $this->getContext(), + $localizer, $this->getUser(), $featureManager ) : null, @@ -300,6 +430,28 @@ class SkinVector22 extends SkinVector { 'vector-page-titlebar-toc', true ), + 'data-vector-sticky-header' => $featureManager->isFeatureEnabled( + Constants::FEATURE_STICKY_HEADER + ) ? new VectorComponentStickyHeader( + $localizer, + new VectorComponentSearchBox( + $parentData['data-search-box'], + // Collapse inside search box is disabled. + false, + false, + 'vector-sticky-search-form', + false, + $config, + Constants::SEARCH_BOX_INPUT_LOCATION_MOVED, + $localizer + ), + // Show sticky ULS if the ULS extension is enabled and the ULS in header is not hidden + $this->isULSExtensionEnabled() && !$this->shouldHideLanguages() ? + new VectorComponentLanguageButton( $ulsLabels[ 'label' ] ) : null, + $featureManager->isFeatureEnabled( + Constants::FEATURE_STICKY_HEADER_EDIT + ) + ) : null ]; foreach ( $components as $key => $component ) { // Array of components or null values. @@ -308,18 +460,6 @@ class SkinVector22 extends SkinVector { } } - $searchStickyHeader = new VectorComponentSearchBox( - $parentData['data-search-box'], - // Collapse inside search box is disabled. - false, - false, - 'vector-sticky-search-form', - false, - $config, - Constants::SEARCH_BOX_INPUT_LOCATION_MOVED, - $this->getContext() - ); - return array_merge( $parentData, [ 'is-language-in-content' => $this->isLanguagesInContent(), 'is-language-in-content-top' => $this->isLanguagesInContentAt( 'top' ), @@ -327,14 +467,6 @@ class SkinVector22 extends SkinVector { 'is-main-menu-visible' => $this->isMainMenuVisible(), // Cast empty string to null 'html-subtitle' => $parentData['html-subtitle'] === '' ? null : $parentData['html-subtitle'], - 'data-vector-sticky-header' => $featureManager->isFeatureEnabled( - Constants::FEATURE_STICKY_HEADER - ) ? $stickyHeader->getTemplateData() + $this->getStickyHeaderData( - $searchStickyHeader->getTemplateData(), - $featureManager->isFeatureEnabled( - Constants::FEATURE_STICKY_HEADER_EDIT - ) - ) : false, 'is-page-tools-enabled' => $isPageToolsEnabled ] ); } diff --git a/includes/SkinVectorLegacy.php b/includes/SkinVectorLegacy.php index efed9793a..a7882d5c9 100644 --- a/includes/SkinVectorLegacy.php +++ b/includes/SkinVectorLegacy.php @@ -4,13 +4,15 @@ namespace MediaWiki\Skins\Vector; use MediaWiki\Skins\Vector\Components\VectorComponentMenuVariants; use MediaWiki\Skins\Vector\Components\VectorComponentSearchBox; +use SkinMustache; +use SkinTemplate; /** * @ingroup Skins * @package Vector * @internal */ -class SkinVectorLegacy extends SkinVector { +class SkinVectorLegacy extends SkinMustache { /** @var int */ private const MENU_TYPE_DEFAULT = 0; /** @var int */ @@ -19,22 +21,12 @@ class SkinVectorLegacy extends SkinVector { private const MENU_TYPE_DROPDOWN = 2; private const MENU_TYPE_PORTAL = 3; - /** - * Show the ULS button if it's modern Vector, languages in header is enabled, - * and the ULS extension is enabled. Hide it otherwise. - * There is no point in showing the language button if ULS extension is unavailable - * as there is no ways to add languages without it. - * @return bool - */ - protected function shouldHideLanguages(): bool { - return true; - } - /** * @inheritDoc */ - protected function isLanguagesInContentAt( $location ) { - return false; + protected function runOnSkinTemplateNavigationHooks( SkinTemplate $skin, &$content_navigation ) { + parent::runOnSkinTemplateNavigationHooks( $skin, $content_navigation ); + Hooks::onSkinTemplateNavigation( $skin, $content_navigation ); } /** @@ -100,10 +92,6 @@ class SkinVectorLegacy extends SkinVector { case 'data-vector-user-menu-overflow': $type = self::MENU_TYPE_DEFAULT; break; - case 'data-languages': - $type = $this->isLanguagesInContent() ? - self::MENU_TYPE_DROPDOWN : self::MENU_TYPE_PORTAL; - break; default: $type = self::MENU_TYPE_PORTAL; break; diff --git a/tests/phpunit/integration/SkinVectorTest.php b/tests/phpunit/integration/SkinVectorTest.php index 5cfb35111..67c8b11de 100644 --- a/tests/phpunit/integration/SkinVectorTest.php +++ b/tests/phpunit/integration/SkinVectorTest.php @@ -48,7 +48,7 @@ class SkinVectorTest extends MediaWikiIntegrationTestCase { } /** - * @covers \MediaWiki\Skins\Vector\SkinVector::getTemplateData + * @covers \MediaWiki\Skins\Vector\SkinVectorLegacy::getTemplateData */ public function testGetTemplateData() { $title = Title::newFromText( 'SkinVector' );