mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-11-24 15:53:46 +00:00
Merge "Refactor: PageTools composes several different components"
This commit is contained in:
commit
2111e91253
55
includes/Components/VectorComponentDropdown.php
Normal file
55
includes/Components/VectorComponentDropdown.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
namespace MediaWiki\Skins\Vector\Components;
|
||||
|
||||
/**
|
||||
* VectorComponentDropdown component
|
||||
*/
|
||||
class VectorComponentDropdown implements VectorComponent {
|
||||
/** @var string */
|
||||
private $id;
|
||||
/** @var string */
|
||||
private $label;
|
||||
/** @var string */
|
||||
private $class;
|
||||
/** @var string */
|
||||
private $tooltip;
|
||||
/** @var string|null */
|
||||
private $icon;
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param string $label
|
||||
* @param string $class
|
||||
* @param string|null $icon
|
||||
* @param string $tooltip
|
||||
*/
|
||||
public function __construct( string $id, string $label, string $class = '', $icon = null, string $tooltip = '' ) {
|
||||
$this->id = $id;
|
||||
$this->label = $label;
|
||||
$this->class = $class;
|
||||
$this->icon = $icon;
|
||||
$this->tooltip = $tooltip;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getTemplateData(): array {
|
||||
$icon = $this->icon;
|
||||
$headingClass = $icon ?
|
||||
'mw-checkbox-hack-button mw-ui-icon mw-ui-button mw-ui-quiet ' .
|
||||
'mw-ui-icon-element mw-ui-icon-wikimedia-' . $icon : '';
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'label' => $this->label,
|
||||
'heading-class' => $headingClass,
|
||||
'html-vector-menu-heading-attributes' => '',
|
||||
'html-vector-menu-checkbox-attributes' => '',
|
||||
'html-vector-heading-icon' => '',
|
||||
'class' => $this->class,
|
||||
'html-tooltip' => $this->tooltip,
|
||||
'checkbox-class' => '',
|
||||
];
|
||||
}
|
||||
}
|
|
@ -92,22 +92,15 @@ class VectorComponentMainMenu implements VectorComponent {
|
|||
$action = $this->optOut;
|
||||
$alert = $this->alert;
|
||||
|
||||
$id = 'vector-main-menu';
|
||||
$pinnableHeader = new VectorComponentPinnableHeader(
|
||||
$this->localizer,
|
||||
false,
|
||||
'vector-main-menu',
|
||||
$id,
|
||||
null
|
||||
);
|
||||
|
||||
$class = $this->getUser()->isAnon() ? 'vector-main-menu-btn-dropdown-anon ' : '';
|
||||
$class .= 'vector-main-menu';
|
||||
return $this->fillMissingData( $this->sidebarData ) + [
|
||||
'id' => 'vector-main-menu',
|
||||
'class' => $class,
|
||||
'label' => $this->localizer->msg( 'vector-main-menu-label' )->text(),
|
||||
// @todo: Helper method for making icon classes would be useful.
|
||||
'heading-class' => 'mw-checkbox-hack-button mw-ui-icon mw-ui-button '
|
||||
. 'mw-ui-quiet mw-ui-icon-wikimedia-menu mw-ui-icon-element',
|
||||
'data-main-menu-action' => $action ? $action->getTemplateData() : null,
|
||||
// T295555 Add language switch alert message temporarily (to be removed).
|
||||
'data-vector-language-switch-alert' => $alert ? $alert->getTemplateData() : null,
|
||||
|
|
|
@ -58,16 +58,15 @@ class VectorComponentPageTools implements VectorComponent {
|
|||
*/
|
||||
public function getTemplateData(): array {
|
||||
$menusData = [ $this->toolbox, $this->actionsMenu ];
|
||||
$id = 'vector-page-tools';
|
||||
$pinnedContainer = new VectorComponentPinnedContainer( $id, $this->isPinned );
|
||||
$pinnableElement = new VectorComponentPinnableElement( $id );
|
||||
|
||||
$pinnableDropdownData = [
|
||||
'id' => 'vector-page-tools',
|
||||
'class' => 'vector-page-tools',
|
||||
'label' => $this->skin->msg( 'toolbox' ),
|
||||
'is-pinned' => $this->isPinned,
|
||||
'has-multiple-menus' => true,
|
||||
$data = $pinnableElement->getTemplateData() +
|
||||
$pinnedContainer->getTemplateData();
|
||||
return $data + [
|
||||
'data-pinnable-header' => $this->pinnableHeader ? $this->pinnableHeader->getTemplateData() : null,
|
||||
'data-menus' => $menusData
|
||||
'data-menus' => $menusData,
|
||||
];
|
||||
return $pinnableDropdownData;
|
||||
}
|
||||
}
|
||||
|
|
26
includes/Components/VectorComponentPinnableElement.php
Normal file
26
includes/Components/VectorComponentPinnableElement.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
namespace MediaWiki\Skins\Vector\Components;
|
||||
|
||||
/**
|
||||
* VectorComponentPinnableElement component
|
||||
*/
|
||||
class VectorComponentPinnableElement implements VectorComponent {
|
||||
/** @var string */
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*/
|
||||
public function __construct( string $id ) {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getTemplateData(): array {
|
||||
return [
|
||||
'id' => $this->id,
|
||||
];
|
||||
}
|
||||
}
|
32
includes/Components/VectorComponentPinnedContainer.php
Normal file
32
includes/Components/VectorComponentPinnedContainer.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
namespace MediaWiki\Skins\Vector\Components;
|
||||
|
||||
/**
|
||||
* VectorComponentPinnedContainer component
|
||||
* To be used with PinnedContainer or UnpinnedContainer templates.
|
||||
*/
|
||||
class VectorComponentPinnedContainer implements VectorComponent {
|
||||
/** @var string */
|
||||
private $id;
|
||||
/** @var bool */
|
||||
private $isPinned;
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param bool $isPinned
|
||||
*/
|
||||
public function __construct( string $id, bool $isPinned = true ) {
|
||||
$this->id = $id;
|
||||
$this->isPinned = $isPinned;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getTemplateData(): array {
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'is-pinned' => $this->isPinned,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -10,6 +10,9 @@ class VectorComponentTableOfContents implements VectorComponent {
|
|||
* @inheritDoc
|
||||
*/
|
||||
public function getTemplateData(): array {
|
||||
return [];
|
||||
$pinnableElementName = 'vector-toc';
|
||||
$pinnedContainer = new VectorComponentPinnedContainer( $pinnableElementName );
|
||||
$pinnableElement = new VectorComponentPinnableElement( $pinnableElementName );
|
||||
return $pinnableElement->getTemplateData() + $pinnedContainer->getTemplateData();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ namespace MediaWiki\Skins\Vector;
|
|||
use ExtensionRegistry;
|
||||
use Linker;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Skins\Vector\Components\VectorComponent;
|
||||
use MediaWiki\Skins\Vector\Components\VectorComponentDropdown;
|
||||
use MediaWiki\Skins\Vector\Components\VectorComponentLanguageButton;
|
||||
use MediaWiki\Skins\Vector\Components\VectorComponentUserLinks;
|
||||
use RuntimeException;
|
||||
|
@ -283,7 +285,7 @@ abstract class SkinVector extends SkinMustache {
|
|||
$returnto = $this->getReturnToParam();
|
||||
$useCombinedLoginLink = $this->useCombinedLoginLink();
|
||||
$userMenuOverflowData = Hooks::updateDropdownMenuData( $overflowMenuData );
|
||||
$userMenuData = Hooks::updateDropdownMenuData( $this->getUserMenuPortletData( $userMenuData ) );
|
||||
$userMenu = $this->getUserMenuDropdown( $userMenuData );
|
||||
unset( $userMenuOverflowData[ 'label' ] );
|
||||
|
||||
if ( $isAnon || $isTempUser ) {
|
||||
|
@ -309,7 +311,8 @@ abstract class SkinVector extends SkinMustache {
|
|||
'is-temp-user' => $isTempUser,
|
||||
'is-wide' => $moreItems > 3,
|
||||
'data-user-menu-overflow' => $userMenuOverflowData,
|
||||
'data-user-menu' => $userMenuData
|
||||
'data-user-menu' => $userMenu->getTemplateData(),
|
||||
'html-items' => $userMenuData['html-items'],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -513,9 +516,9 @@ abstract class SkinVector extends SkinMustache {
|
|||
* FIXME: Move to VectorComponentUserMenu
|
||||
*
|
||||
* @param array $portletData
|
||||
* @return array
|
||||
* @return VectorComponent
|
||||
*/
|
||||
private function getUserMenuPortletData( $portletData ) {
|
||||
private function getUserMenuDropdown( $portletData ): VectorComponent {
|
||||
// T317789: Core can undesirably add an 'emptyPortlet' class that hides the
|
||||
// user menu. This is a result of us manually removing items from the menu
|
||||
// in Hooks::updateUserLinksDropdownItems which can make
|
||||
|
@ -543,9 +546,8 @@ abstract class SkinVector extends SkinMustache {
|
|||
// This overrides the tooltip for the user links menu icon which is an ellipsis for anonymous users.
|
||||
$portletData['html-tooltip'] = Linker::tooltip( 'vector-anon-user-menu-title' );
|
||||
}
|
||||
$portletData['icon'] = $icon;
|
||||
$portletData['button'] = true;
|
||||
$portletData['text-hidden'] = true;
|
||||
return $portletData;
|
||||
return new VectorComponentDropdown(
|
||||
$portletData['id'], $portletData['label'], $portletData['class'], $icon, $portletData['html-tooltip'] ?? ''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace MediaWiki\Skins\Vector;
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Skins\Vector\Components\VectorComponentDropdown;
|
||||
use MediaWiki\Skins\Vector\Components\VectorComponentMainMenu;
|
||||
use MediaWiki\Skins\Vector\Components\VectorComponentPageTools;
|
||||
use MediaWiki\Skins\Vector\Components\VectorComponentPinnableHeader;
|
||||
|
@ -71,7 +72,6 @@ class SkinVector22 extends SkinVector {
|
|||
|
||||
// ToC is pinned by default, hardcoded for now
|
||||
$isTocPinned = true;
|
||||
$pinnableElementName = 'vector-toc';
|
||||
$pinnableHeader = new VectorComponentPinnableHeader(
|
||||
$this->getContext(),
|
||||
$isTocPinned,
|
||||
|
@ -89,8 +89,6 @@ class SkinVector22 extends SkinVector {
|
|||
$tocData[ 'number-section-count'] >= $this->getConfig()->get(
|
||||
'VectorTableOfContentsCollapseAtCount'
|
||||
),
|
||||
// Needed for PinnedContainer
|
||||
'id' => $pinnableElementName,
|
||||
'is-pinned' => $isTocPinned,
|
||||
'data-pinnable-header' => $pinnableHeader->getTemplateData(),
|
||||
] );
|
||||
|
@ -237,6 +235,15 @@ class SkinVector22 extends SkinVector {
|
|||
}
|
||||
}
|
||||
$config = $this->getConfig();
|
||||
$mainMenuDropdownClass = $this->getUser()->isAnon() ? 'vector-main-menu-btn-dropdown-anon ' : '';
|
||||
$mainMenuDropdownClass .= 'vector-main-menu-dropdown';
|
||||
$mainMenuDropdown = new VectorComponentDropdown(
|
||||
'vector-main-menu-dropdown',
|
||||
$this->msg( 'vector-main-menu-label' )->text(),
|
||||
$mainMenuDropdownClass,
|
||||
'menu'
|
||||
);
|
||||
|
||||
$components = [
|
||||
'data-search-box' => new VectorComponentSearchBox(
|
||||
$parentData['data-search-box'],
|
||||
|
@ -249,6 +256,7 @@ class SkinVector22 extends SkinVector {
|
|||
Constants::SEARCH_BOX_INPUT_LOCATION_MOVED,
|
||||
$this->getContext()
|
||||
),
|
||||
'data-main-menu-dropdown' => $mainMenuDropdown,
|
||||
'data-portlets-main-menu' => new VectorComponentMainMenu(
|
||||
$sidebar,
|
||||
$this,
|
||||
|
@ -261,6 +269,8 @@ class SkinVector22 extends SkinVector {
|
|||
$isPageToolsPinned,
|
||||
$this
|
||||
) : null,
|
||||
'data-page-tools-dropdown' => $isPageToolsEnabled ?
|
||||
new VectorComponentDropdown( 'vector-page-tools', $this->msg( 'toolbox' )->text() ) : null,
|
||||
];
|
||||
foreach ( $components as $key => $component ) {
|
||||
// Array of components or null values.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{{! Use `.vector-main-menu.vector-dropdown` to target styles at this element}}
|
||||
{{>Dropdown/Open}}
|
||||
{{#data-main-menu-dropdown}}{{>Dropdown/Open}}{{/data-main-menu-dropdown}}
|
||||
{{#data-portlets-main-menu}}{{>MainMenuContents}}{{/data-portlets-main-menu}}
|
||||
{{>Dropdown/Close}}
|
||||
{{#data-main-menu-dropdown}}{{>Dropdown/Close}}{{/data-main-menu-dropdown}}
|
||||
|
|
|
@ -13,13 +13,15 @@
|
|||
</nav>
|
||||
|
||||
<nav class="vector-page-tools-landmark" aria-label="{{msg-tooltip-p-cactions}}">
|
||||
{{#is-page-tools-enabled}}{{#data-page-tools}}
|
||||
{{>Dropdown/Open}}
|
||||
{{#is-page-tools-enabled}}
|
||||
{{#data-page-tools-dropdown}}{{>Dropdown/Open}}{{/data-page-tools-dropdown}}
|
||||
{{#data-page-tools}}
|
||||
{{>PinnableContainer/Unpinned/Open}}
|
||||
{{^is-pinned}}{{>PageTools}}{{/is-pinned}}
|
||||
{{>PinnableContainer/Close}}
|
||||
{{>Dropdown/Close}}
|
||||
{{/data-page-tools}}{{/is-page-tools-enabled}}
|
||||
{{/data-page-tools}}
|
||||
{{#data-page-tools-dropdown}}{{>Dropdown/Close}}{{/data-page-tools-dropdown}}
|
||||
{{/is-page-tools-enabled}}
|
||||
{{^is-page-tools-enabled}}{{#data-actions}}{{>LegacyMoreMenu}}{{/data-actions}}{{/is-page-tools-enabled}}
|
||||
</nav>
|
||||
</div>
|
||||
|
|
|
@ -132,7 +132,6 @@ class SkinVectorTest extends MediaWikiIntegrationTestCase {
|
|||
'pin-label' => '(vector-pin-element-label)',
|
||||
'label-tag-name' => 'h2'
|
||||
],
|
||||
'id' => 'vector-toc',
|
||||
'is-pinned' => true,
|
||||
];
|
||||
$expectedNestedTocData = array_merge( $nestedTocData, $expectedConfigData );
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
/**
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file
|
||||
* @since 1.35
|
||||
*/
|
||||
|
||||
namespace MediaWiki\Skins\Vector\Tests\Unit\Components;
|
||||
|
||||
use MediaWiki\Skins\Vector\Components\VectorComponentTableOfContents;
|
||||
|
||||
/**
|
||||
* @group Vector
|
||||
* @group Components
|
||||
* @coversDefaultClass \MediaWiki\Skins\Vector\Components\VectorComponentTableOfContents
|
||||
*/
|
||||
class VectorComponentTableOfContentsTest extends \MediaWikiUnitTestCase {
|
||||
/**
|
||||
* @covers ::getTemplateData
|
||||
*/
|
||||
public function testGetTemplateData() {
|
||||
$toc = new VectorComponentTableOfContents();
|
||||
$this->assertEquals(
|
||||
[
|
||||
'id' => 'vector-toc',
|
||||
'is-pinned' => true,
|
||||
],
|
||||
$toc->getTemplateData()
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue