Hygiene: Drop optional parameters from SingleMenuEntry constructor

The SingleMenuEntry constructor has too many optional parameters
which makes it confusing and dificult to use.
Instead system should provide a named constructor `create` that
creates new menu entry instance with Icon and click tracking enabled.
If developer wants to override event tracking/change icon it is
possible via calling `trackClicks` and `setIcon` method calls.

This is a first refactoring step to simplify the SingleMenuEntry,
the next follow-up will remove unnecessary PageActionsDirector.

Bug: T232734
Change-Id: I7a631a635a5c5932845639123c285d1d18df1b5d
This commit is contained in:
Piotr Miazga 2019-11-07 19:04:21 +01:00
parent 10defb5aa1
commit 4c224d2657
6 changed files with 63 additions and 36 deletions

View file

@ -75,7 +75,7 @@ final class Definitions {
* @throws MWException
*/
public function insertContributionsMenuItem( Group $group ) {
$group->insertEntry( new SingleMenuEntry(
$group->insertEntry( SingleMenuEntry::create(
'contributions',
$this->context->msg( 'mobile-frontend-main-menu-contributions' )->escaped(),
SpecialPage::getTitleFor( 'Contributions', $this->user->getName() )->getLocalURL()
@ -104,7 +104,7 @@ final class Definitions {
$watchlistQuery['filter'] = $filter;
}
}
$group->insertEntry( new SingleMenuEntry(
$group->insertEntry( SingleMenuEntry::create(
'watchlist',
$this->context->msg( 'mobile-frontend-main-menu-watchlist' )->escaped(),
$watchTitle->getLocalURL( $watchlistQuery )
@ -209,7 +209,7 @@ final class Definitions {
$title = $this->context->getTitle();
$returnToTitle = $title->getPrefixedText();
$group->insertEntry( new SingleMenuEntry(
$group->insertEntry( SingleMenuEntry::create(
'settings',
$this->context->msg( 'mobile-frontend-main-menu-settings' )->escaped(),
SpecialPage::getTitleFor( 'MobileOptions' )
@ -223,13 +223,13 @@ final class Definitions {
* @throws MWException
*/
public function insertPreferencesItem( Group $group ) {
$group->insertEntry( new SingleMenuEntry(
$entry = SingleMenuEntry::create(
'preferences',
$this->context->msg( 'preferences' )->escaped(),
SpecialPage::getTitleFor( 'Preferences' )->getLocalURL(),
true,
'settings'
) );
SpecialPage::getTitleFor( 'Preferences' )->getLocalURL()
);
$entry->setIcon( 'settings' );
$group->insertEntry( $entry );
}
/**
@ -283,7 +283,7 @@ final class Definitions {
*/
public function insertSpecialPages( Group $group ) {
$group->insertEntry(
new SingleMenuEntry(
SingleMenuEntry::create(
'specialpages',
$this->context->msg( 'specialpages' )->escaped(),
SpecialPage::getTitleFor( 'Specialpages' )->getLocalURL()
@ -311,7 +311,7 @@ final class Definitions {
return;
}
$group->insertEntry( new SingleMenuEntry(
$group->insertEntry( SingleMenuEntry::create(
'communityportal',
$title->getText(),
$title->getLocalURL()

View file

@ -37,7 +37,7 @@ interface IMenuEntry {
/**
* Returns the list of components of the menu entry
*
* Each component is an array with:
* Each component is an array of HTML attributes with at least:
* - text -> text to show
* - href -> href attribute
* - class -> css class applied to it

View file

@ -29,5 +29,7 @@ final class LogInMenuEntry extends SingleMenuEntry {
$text = $messageLocalizer->msg( 'mobile-frontend-main-menu-login' )->escaped();
$url = SpecialPage::getTitleFor( 'Userlogin' )->getLocalURL( $authLinksQuery );
parent::__construct( 'login', $text, $url );
$this->trackClicks( 'login' );
$this->setIcon( 'login' );
}
}

View file

@ -32,6 +32,8 @@ final class LogOutMenuEntry extends SingleMenuEntry {
) {
$text = $messageLocalizer->msg( 'mobile-frontend-main-menu-logout' )->escaped();
$url = SpecialPage::getTitleFor( 'Userlogout' )->getLocalURL( $authLinksQuery );
parent::__construct( 'logout', $text, $url, true, null, $iconType, $classes );
parent::__construct( 'logout', $text, $url, $classes );
$this->trackClicks( 'logout' );
$this->setIcon( 'logout', $iconType );
}
}

View file

@ -30,7 +30,7 @@ class SingleMenuEntry implements IMenuEntry {
/**
* @var array
*/
private $component;
private $attributes;
/**
* Create a simple menu element with one component
@ -38,27 +38,49 @@ class SingleMenuEntry implements IMenuEntry {
* @param string $name An unique menu element identifier
* @param string $text Text to show on menu element
* @param string $url URL menu element points to
* @param bool|string $trackClicks Should clicks be tracked. To override the tracking code
* pass the tracking code as string
* @param string|null $iconName The Icon name, if not defined, the $name will be used
* @param string $iconType 'before' or 'element'
* @param string $classes Additional CSS class names.
* @param string $className Additional CSS class names.
*/
public function __construct(
$name, $text, $url, $trackClicks = true, $iconName = null, $iconType = 'before', $classes = ''
) {
public function __construct( $name, $text, $url, $className = '' ) {
$this->name = $name;
$this->component = [
$this->attributes = [
'text' => $text,
'href' => $url,
'class' => MinervaUI::iconClass( $iconName ?? $name, $iconType, $classes ),
'class' => $className
];
if ( $trackClicks !== false ) {
$eventName = $trackClicks === true ? $name : $trackClicks;
if ( $eventName ) {
$this->component['data-event-name'] = 'menu.' . $eventName;
}
}
}
/**
* Create a Single Menu entry with text, icon and active click tracking
*
* @param string $name Entry identifier
* @param string $text Entry label
* @param string $url The URL entry points to
* @param string $className Optional HTML classes
* @return static
*/
public static function create( $name, $text, $url, $className = '' ) {
$entry = new static( $name, $text, $url, $className );
$entry->trackClicks( $name );
$entry->setIcon( $name );
return $entry;
}
/**
* @param string $eventName Should clicks be tracked. To override the tracking code
* pass the tracking code as string
*/
public function trackClicks( $eventName ) {
$this->attributes['data-event-name'] = 'menu.' . $eventName;
}
/**
* Set the Menu entry icon
* @param string $iconName Icon name
* @param string $iconType Icon type
*/
public function setIcon( $iconName, $iconType = 'before' ) {
$this->attributes['class'] .= ' ' . MinervaUI::iconClass( $iconName, $iconType, '' );
}
/**
@ -79,6 +101,7 @@ class SingleMenuEntry implements IMenuEntry {
* @inheritDoc
*/
public function getComponents(): array {
return [ $this->component ];
return [ $this->attributes ];
}
}

View file

@ -70,19 +70,19 @@ final class AdvancedUserMenuBuilder implements IUserMenuBuilder {
$group->insertEntry( new ProfileMenuEntry( $this->user ) );
$talkPage = $this->user->getUserPage()->getTalkPageIfDefined();
if ( $talkPage ) {
$group->insertEntry( new SingleMenuEntry( 'userTalk',
$entry = SingleMenuEntry::create(
'userTalk',
$this->messageLocalizer->msg( 'mobile-frontend-user-page-talk' )->escaped(),
$talkPage->getLocalURL(),
true,
null,
'before',
'wikimedia-ui-userTalk-base20'
) );
);
$entry->setIcon( null, 'before' );
$group->insertEntry( $entry );
}
$sandbox = $personalTools['sandbox']['links'][0] ?? false;
if ( $sandbox ) {
$group->insertEntry( new SingleMenuEntry(
$group->insertEntry( SingleMenuEntry::create(
'userSandbox',
$sandbox['text'],
$sandbox['href']