Provide IMenuEntry interface

The Group shouldn't depend upon concrete MenuEntry definition.
Different Menus can present different MenuElements. Code should
allow easy extensions, not limit only to single MenuEntry
definition.

Changes:
 - introduced IMenuEntry interface
 - MenuEntry implements IMenuEntry
 - removed isJSOnly from logic as it's related only to one menu
 element (Watchstar) and Group shouldn't be aware of some special
 handling for some elements. The IMenuEntry shouldn't define this
 method
 - getName, getComponents, getCSSClasses should have defined return
 types

Bug: 1221792
Change-Id: I0646df734e869c26bfa8c3a772200e8258a8acce
This commit is contained in:
Piotr Miazga 2019-05-14 12:31:54 +02:00
parent 6c70498e91
commit 6905b85d67
4 changed files with 75 additions and 15 deletions

View File

@ -27,7 +27,7 @@ use DomainException;
*/
class Group {
/**
* @var MenuEntry[]
* @var IMenuEntry[]
*/
private $entries = [];
@ -46,14 +46,14 @@ class Group {
* @return array
*/
public function getEntries() {
$entryPresenter = function ( MenuEntry $entry ) {
$entryPresenter = function ( IMenuEntry $entry ) {
$result = [
'name' => $entry->getName(),
'components' => $entry->getComponents(),
];
if ( $entry->isJSOnly() ) {
$result['class'] = 'jsonly';
$classes = $entry->getCSSClasses();
if ( $classes ) {
$result[ 'class' ] = implode( ' ', $classes );
}
return $result;
@ -74,6 +74,16 @@ class Group {
}
}
/**
* Insert new menu entry
* @param IMenuEntry $entry
* @throws DomainException When the entry already exists
*/
public function insertEntry( IMenuEntry $entry ) {
$this->throwIfNotUnique( $entry->getName() );
$this->entries[] = $entry;
}
/**
* Insert an entry into the menu.
*
@ -119,7 +129,6 @@ class Group {
*/
public function insertAfter( $targetName, $name, $isJSOnly = false ) {
$this->throwIfNotUnique( $name );
$index = $this->search( $targetName );
if ( $index === -1 ) {

View File

@ -0,0 +1,48 @@
<?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.
*/
namespace MediaWiki\Minerva\Menu;
/**
* Model for a menu entry.
*/
interface IMenuEntry {
/**
* Get the menu entry name/identifier
* @return string
*/
public function getName();
/**
* Get the CSS classes that should be applied to the element
* @return string[]
*/
public function getCSSClasses(): array;
/**
* Returns the list of components of the menu entry
*
* Each component is an array with:
* - text -> text to show
* - href -> href attribute
* - class -> css class applied to it
* @return array
*/
public function getComponents(): array;
}

View File

@ -20,7 +20,7 @@ namespace MediaWiki\Minerva\Menu;
/**
* Model for a menu entry.
*/
class MenuEntry {
class MenuEntry implements IMenuEntry {
private $name;
private $isJSOnly;
private $components;
@ -43,19 +43,22 @@ class MenuEntry {
}
/**
* Gets whether the entry should only be shown if JavaScript is disabled
* in the client.
* Return the CSS classes applied to the Menu element
*
* @return bool
* @return array
*/
public function isJSOnly() {
return $this->isJSOnly;
public function getCSSClasses(): array {
$classes = [];
if ( $this->isJSOnly ) {
$classes[] = 'jsonly';
}
return $classes;
}
/**
* @return array
*/
public function getComponents() {
public function getComponents(): array {
return $this->components;
}

View File

@ -13,7 +13,7 @@ class MenuEntryTest extends \MediaWikiTestCase {
/**
* @covers ::__construct
* @covers ::getName()
* @covers ::isJSOnly()
* @covers ::getCSSClasses()
* @covers ::getComponents()
*/
public function testMenuEntryConstruction() {
@ -21,7 +21,7 @@ class MenuEntryTest extends \MediaWikiTestCase {
$isJSOnly = true;
$entry = new MenuEntry( $name, $isJSOnly );
$this->assertSame( $name, $entry->getName() );
$this->assertSame( $isJSOnly, $entry->isJSOnly() );
$this->assertArrayEquals( [ 'jsonly' ], $entry->getCSSClasses() );
$this->assertSame( [], $entry->getComponents() );
}
}