mediawiki-skins-Vector/includes/Components/VectorComponentStickyHeader.php
Moh'd Khier Abualruz 0903ecba9c Vector sticky header dynamic edit icons order
Problem: Edit-links are shown in static order in sticky header always source edit 1st, then visual editor

Patch Changes:
- We now read the configuration from the visual editor extension.
- Based on the order that page views portlet shows of the tabs, we add the icons to the sticky header in the same order as it shows in the portlet.

Bug: T318447
Change-Id: I2d926bf84131b13c881b09c87ccd5d2010c0dffc
2023-10-12 18:54:47 +02:00

190 lines
4.9 KiB
PHP

<?php
namespace MediaWiki\Skins\Vector\Components;
use Message;
use MessageLocalizer;
/**
* VectorComponentStickyHeader component
*/
class VectorComponentStickyHeader implements VectorComponent {
private const TALK_ICON = [
'icon' => 'speechBubbles',
'id' => 'ca-talk-sticky-header',
'event' => 'talk-sticky-header'
];
private const SUBJECT_ICON = [
'icon' => 'article',
'id' => 'ca-subject-sticky-header',
'event' => 'subject-sticky-header'
];
private const HISTORY_ICON = [
'icon' => 'wikimedia-history',
'id' => 'ca-history-sticky-header',
'event' => 'history-sticky-header',
];
// Event and icon will be updated depending on watchstar state
private const WATCHSTAR_ICON = [
'id' => 'ca-watchstar-sticky-header',
'event' => 'watch-sticky-header',
'icon' => 'wikimedia-star',
'is-quiet' => true,
'tabindex' => '-1',
// With the original watchstar, this class is applied to the <li> element
// thats the parent of the actual watchlink. In the sticky header we dont use
// the same markup, so its directly applied to the watchlink element
'class' => 'mw-watchlink'
];
private const EDIT_VE_ICON = [
'id' => 'ca-ve-edit-sticky-header',
'event' => 've-edit-sticky-header',
'icon' => 'wikimedia-edit',
];
private const EDIT_WIKITEXT_ICON = [
'id' => 'ca-edit-sticky-header',
'event' => 'wikitext-edit-sticky-header',
'icon' => 'wikimedia-wikiText',
];
private const EDIT_PROTECTED_ICON = [
'href' => '#',
'id' => 'ca-viewsource-sticky-header',
'event' => 've-edit-protected-sticky-header',
'icon' => 'wikimedia-editLock',
];
/** @var MessageLocalizer */
private $localizer;
/** @var VectorComponent */
private $search;
/** @var VectorComponent|null */
private $langButton;
/** @var bool */
private $visualEditorTabPositionFirst;
/**
* @param MessageLocalizer $localizer
* @param VectorComponent $searchBox
* @param VectorComponent|null $langButton
* @param bool $visualEditorTabPositionFirst
*/
public function __construct(
MessageLocalizer $localizer,
VectorComponent $searchBox,
$langButton = null,
bool $visualEditorTabPositionFirst = false
) {
$this->search = $searchBox;
$this->langButton = $langButton;
$this->localizer = $localizer;
$this->visualEditorTabPositionFirst = $visualEditorTabPositionFirst;
}
/**
* @param mixed $key
* @return Message
*/
private function msg( $key ): Message {
return $this->localizer->msg( $key );
}
/**
* Creates array of Button components in the sticky header
*
* @return array
*/
private function getIconButtons() {
$icons = [
self::TALK_ICON,
self::SUBJECT_ICON,
self::HISTORY_ICON,
self::WATCHSTAR_ICON,
];
$icons[] = $this->visualEditorTabPositionFirst ? self::EDIT_VE_ICON : self::EDIT_WIKITEXT_ICON;
$icons[] = $this->visualEditorTabPositionFirst ? self::EDIT_WIKITEXT_ICON : self::EDIT_VE_ICON;
$icons[] = self::EDIT_PROTECTED_ICON;
$iconButtons = [];
foreach ( $icons as $icon ) {
$iconButtons[] = new VectorComponentButton(
// Button labels will be populated in stickyHeader.js
"",
$icon[ 'icon' ],
$icon[ 'id' ],
$icon[ 'class' ] ?? '',
[
'tabindex' => '-1',
'data-event-name' => $icon[ 'event' ],
],
'quiet',
'default',
true,
'#'
);
}
return $iconButtons;
}
/**
* Creates button data for the "Add section" button in the sticky header
*
* @return VectorComponentButton
*/
private function getAddSectionButton() {
return new VectorComponentButton(
$this->msg( [ 'vector-2022-action-addsection', 'skin-action-addsection' ] )->text(),
'speechBubbleAdd-progressive',
'ca-addsection-sticky-header',
'',
[
'tabindex' => '-1',
'data-event-name' => 'addsection-sticky-header'
],
'quiet',
'progressive',
false,
'#'
);
}
/**
* Creates button data for the "search" button in the sticky header
*
* @param array $searchBoxData
* @return VectorComponentButton
*/
private function getSearchButton( $searchBoxData ) {
return new VectorComponentButton(
$this->msg( 'search' ),
'search',
'',
'vector-sticky-header-search-toggle',
[
'tabindex' => '-1',
'data-event-name' => 'ui.' . $searchBoxData['form-id'] . '.icon'
],
'quiet',
'default',
true
);
}
/**
* @inheritDoc
*/
public function getTemplateData(): array {
$iconButtonData = array_map( static function ( $btn ) {
return $btn->getTemplateData();
}, $this->getIconButtons() );
$buttonData = $this->langButton ? [ $this->langButton->getTemplateData() ] : [];
$buttonData[] = $this->getAddSectionButton()->getTemplateData();
$searchBoxData = $this->search->getTemplateData();
$searchButtonData = $this->getSearchButton( $searchBoxData )->getTemplateData();
return [
'array-icon-buttons' => $iconButtonData,
'array-buttons' => $buttonData,
'data-button-start' => $searchButtonData,
'data-search' => $searchBoxData,
];
}
}