mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/MinervaNeue
synced 2024-11-27 23:50:30 +00:00
Provide a code structure for menus handling and add Advanced menu
Changes: - moved all menu elements definitions from SkinMinerva into a separate Definitions.php file - moved menu building from SkinMinerva into includes/menu/Main folder - introduced Builder pattern for easy menu building Minerva/Menu/Main/Director takes an Minerva/Menu/Main/IBuilder and builds the menu. The IBuilders use definitions from Minerva/Menu/Definitions file, so all definitions can be shared across different menus - used ServiceWiring file to register MainMenu Director as Service - left class_alias for old MenuBuilder as some extensions still use it - The hooks system have to stay like that as some extensions are using it (BlueSpiceMultiUpload and GrowthExperiments). - introduced AdvancedMenu builder for the AMC mode Bug: T216152 Change-Id: I210c3f1fa36bbd2f9108d728b12cbb21ee210354
This commit is contained in:
parent
258e635ae5
commit
1f4582cc09
|
@ -1,6 +1,29 @@
|
|||
<?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
|
||||
*/
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Minerva\Menu\Definitions;
|
||||
use MediaWiki\Minerva\Menu\Main\AdvancedBuilder;
|
||||
use MediaWiki\Minerva\Menu\Main\DefaultBuilder;
|
||||
use MediaWiki\Minerva\Menu\Main\Director;
|
||||
use MediaWiki\Minerva\SkinOptions;
|
||||
use MediaWiki\Minerva\SkinUserPageHelper;
|
||||
|
||||
|
@ -8,6 +31,19 @@ return [
|
|||
'Minerva.ContentHandler' => function ( MediaWikiServices $services ) {
|
||||
return ContentHandler::getForTitle( RequestContext::getMain()->getTitle() );
|
||||
},
|
||||
'Minerva.Menu.MainDirector' => function ( MediaWikiServices $services ) {
|
||||
$context = RequestContext::getMain();
|
||||
/** @var SkinOptions $options */
|
||||
$options = $services->getService( 'Minerva.SkinOptions' );
|
||||
$showMobileOptions = $options->get( SkinOptions::OPTION_MOBILE_OPTIONS );
|
||||
$user = $context->getUser();
|
||||
$definitions = new Definitions( $context, $services->getSpecialPageFactory() );
|
||||
$builder = $options->get( SkinOptions::OPTION_AMC ) ?
|
||||
new AdvancedBuilder( $showMobileOptions, $user, $definitions ) :
|
||||
new DefaultBuilder( $showMobileOptions, $user, $definitions );
|
||||
|
||||
return new Director( $builder );
|
||||
},
|
||||
'Minerva.SkinUserPageHelper' => function ( MediaWikiServices $services ) {
|
||||
return new SkinUserPageHelper( RequestContext::getMain()->getTitle() );
|
||||
},
|
||||
|
|
332
includes/menu/Definitions.php
Normal file
332
includes/menu/Definitions.php
Normal file
|
@ -0,0 +1,332 @@
|
|||
<?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
|
||||
*/
|
||||
|
||||
namespace MediaWiki\Minerva\Menu;
|
||||
|
||||
use IContextSource;
|
||||
use MediaWiki\Special\SpecialPageFactory;
|
||||
use MinervaUI;
|
||||
use MWException;
|
||||
use SpecialMobileWatchlist;
|
||||
use SpecialPage;
|
||||
use Title;
|
||||
use User;
|
||||
|
||||
/**
|
||||
* Set of all know menu items for easier building
|
||||
*/
|
||||
final class Definitions {
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* @var IContextSource
|
||||
*/
|
||||
private $context;
|
||||
|
||||
/**
|
||||
* @var SpecialPageFactory
|
||||
*/
|
||||
private $specialPageFactory;
|
||||
|
||||
/**
|
||||
* Initialize definitions helper class
|
||||
*
|
||||
* @param IContextSource $context
|
||||
* @param SpecialPageFactory $factory
|
||||
*/
|
||||
public function __construct( IContextSource $context, SpecialPageFactory $factory ) {
|
||||
$this->user = $context->getUser();
|
||||
$this->context = $context;
|
||||
$this->specialPageFactory = $factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the Contributions menu item into the menu.
|
||||
*
|
||||
* @param Group $group
|
||||
* @throws MWException
|
||||
*/
|
||||
public function insertContributionsMenuItem( Group $group ) {
|
||||
$group->insert( 'contribs' )
|
||||
->addComponent(
|
||||
$this->context->msg( 'mobile-frontend-main-menu-contributions' )->escaped(),
|
||||
SpecialPage::getTitleFor( 'Contributions', $this->user->getName() )->getLocalUrl(),
|
||||
MinervaUI::iconClass( 'contributions', 'before' ),
|
||||
[ 'data-event-name' => 'contributions' ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the Watchlist menu item into the menu for a logged in user
|
||||
*
|
||||
* @param Group $group
|
||||
* @throws MWException
|
||||
*/
|
||||
public function insertWatchlistMenuItem( Group $group ) {
|
||||
$watchTitle = SpecialPage::getTitleFor( 'Watchlist' );
|
||||
|
||||
// Watchlist link
|
||||
$watchlistQuery = [];
|
||||
// Avoid fatal when MobileFrontend not available (T171241)
|
||||
if ( class_exists( 'SpecialMobileWatchlist' ) ) {
|
||||
$view = $this->user->getOption( SpecialMobileWatchlist::VIEW_OPTION_NAME, false );
|
||||
$filter = $this->user->getOption( SpecialMobileWatchlist::FILTER_OPTION_NAME, false );
|
||||
if ( $view ) {
|
||||
$watchlistQuery['watchlistview'] = $view;
|
||||
}
|
||||
if ( $filter && $view === 'feed' ) {
|
||||
$watchlistQuery['filter'] = $filter;
|
||||
}
|
||||
}
|
||||
|
||||
$group->insert( 'watchlist' )
|
||||
->addComponent(
|
||||
$this->context->msg( 'mobile-frontend-main-menu-watchlist' )->escaped(),
|
||||
$watchTitle->getLocalURL( $watchlistQuery ),
|
||||
MinervaUI::iconClass( 'watchlist', 'before' ),
|
||||
[ 'data-event-name' => 'watchlist' ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a login or logout button
|
||||
*
|
||||
* @param Group $group
|
||||
* @throws MWException
|
||||
*/
|
||||
public function insertLogInOutMenuItem( Group $group ) {
|
||||
$query = [];
|
||||
$returntoquery = [];
|
||||
$request = $this->context->getRequest();
|
||||
|
||||
if ( !$request->wasPosted() ) {
|
||||
$returntoquery = $request->getValues();
|
||||
unset( $returntoquery['title'] );
|
||||
unset( $returntoquery['returnto'] );
|
||||
unset( $returntoquery['returntoquery'] );
|
||||
}
|
||||
$title = $this->context->getTitle();
|
||||
// Don't ever redirect back to the login page (bug 55379)
|
||||
if ( !$title->isSpecial( 'Userlogin' ) ) {
|
||||
$query[ 'returnto' ] = $title->getPrefixedText();
|
||||
}
|
||||
|
||||
if ( $this->user->isLoggedIn() ) {
|
||||
if ( !empty( $returntoquery ) ) {
|
||||
$query[ 'returntoquery' ] = wfArrayToCgi( $returntoquery );
|
||||
}
|
||||
$url = SpecialPage::getTitleFor( 'Userlogout' )->getLocalURL( $query );
|
||||
$username = $this->user->getName();
|
||||
|
||||
$group->insert( 'auth', false )
|
||||
->addComponent(
|
||||
$username,
|
||||
Title::newFromText( $username, NS_USER )->getLocalUrl(),
|
||||
MinervaUI::iconClass( 'profile', 'before', 'truncated-text primary-action' ),
|
||||
[ 'data-event-name' => 'profile' ]
|
||||
)
|
||||
->addComponent(
|
||||
$this->context->msg( 'mobile-frontend-main-menu-logout' )->escaped(),
|
||||
$url,
|
||||
MinervaUI::iconClass(
|
||||
'logout', 'element', 'secondary-action truncated-text' ),
|
||||
[ 'data-event-name' => 'logout' ]
|
||||
);
|
||||
} else {
|
||||
// unset campaign on login link so as not to interfere with A/B tests
|
||||
unset( $returntoquery['campaign'] );
|
||||
$query[ 'returntoquery' ] = wfArrayToCgi( $returntoquery );
|
||||
$url = $this->getLoginUrl( $query );
|
||||
$group->insert( 'auth', false )
|
||||
->addComponent(
|
||||
$this->context->msg( 'mobile-frontend-main-menu-login' )->escaped(),
|
||||
$url,
|
||||
MinervaUI::iconClass( 'login', 'before' ),
|
||||
[ 'data-event-name' => 'login' ]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and insert Home link
|
||||
* @param Group $group
|
||||
*/
|
||||
public function insertHomeItem( Group $group ) {
|
||||
// Home link
|
||||
$group->insert( 'home' )
|
||||
->addComponent(
|
||||
$this->context->msg( 'mobile-frontend-home-button' )->escaped(),
|
||||
Title::newMainPage()->getLocalUrl(),
|
||||
MinervaUI::iconClass( 'home', 'before' ),
|
||||
[ 'data-event-name' => 'home' ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and insert Random link
|
||||
* @param Group $group
|
||||
* @throws MWException
|
||||
*/
|
||||
public function insertRandomItem( Group $group ) {
|
||||
// Random link
|
||||
$group->insert( 'random' )
|
||||
->addComponent( $this->context->msg( 'mobile-frontend-random-button' )->escaped(),
|
||||
SpecialPage::getTitleFor( 'Randompage' )->getLocalUrl() . '#/random',
|
||||
MinervaUI::iconClass( 'random', 'before' ), [
|
||||
'id' => 'randomButton',
|
||||
'data-event-name' => 'random',
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* If Nearby is supported, build and inject the Nearby link
|
||||
* @param Group $group
|
||||
* @throws MWException
|
||||
*/
|
||||
public function insertNearbyIfSupported( Group $group ) {
|
||||
// Nearby link (if supported)
|
||||
if ( $this->specialPageFactory->exists( 'Nearby' ) ) {
|
||||
$group->insert( 'nearby', $isJSOnly = true )
|
||||
->addComponent(
|
||||
$this->context->msg( 'mobile-frontend-main-menu-nearby' )->escaped(),
|
||||
SpecialPage::getTitleFor( 'Nearby' )->getLocalURL(),
|
||||
MinervaUI::iconClass( 'nearby', 'before', 'nearby' ),
|
||||
[ 'data-event-name' => 'nearby' ]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and insert the Settings link
|
||||
* @param Group $group
|
||||
* @throws MWException
|
||||
*/
|
||||
public function insertMobileOptionsItem( Group $group ) {
|
||||
$title = $this->context->getTitle();
|
||||
$returnToTitle = $title->getPrefixedText();
|
||||
$group->insert( 'settings' )
|
||||
->addComponent(
|
||||
$this->context->msg( 'mobile-frontend-main-menu-settings' )->escaped(),
|
||||
SpecialPage::getTitleFor( 'MobileOptions' )->
|
||||
getLocalURL( [ 'returnto' => $returnToTitle ] ),
|
||||
MinervaUI::iconClass( 'settings', 'before' ),
|
||||
[ 'data-event-name' => 'settings' ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and insert the Preferences link
|
||||
* @param Group $group
|
||||
* @throws MWException
|
||||
*/
|
||||
public function insertPreferencesItem( Group $group ) {
|
||||
$group->insert( 'preferences' )
|
||||
->addComponent(
|
||||
$this->context->msg( 'preferences' )->escaped(),
|
||||
SpecialPage::getTitleFor( 'Preferences' )->getLocalURL(),
|
||||
MinervaUI::iconClass( 'settings', 'before' ),
|
||||
[ 'data-event-name' => 'preferences' ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and insert About page link
|
||||
* @param Group $group
|
||||
*/
|
||||
public function insertAboutItem( Group $group ) {
|
||||
$title = Title::newFromText( $this->context->msg( 'aboutpage' )->inContentLanguage()->text() );
|
||||
$msg = $this->context->msg( 'aboutsite' );
|
||||
if ( $title && !$msg->isDisabled() ) {
|
||||
$group->insert( 'about' )
|
||||
->addComponent( $msg->text(), $title->getLocalUrl() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and insert Disclaimers link
|
||||
* @param Group $group
|
||||
*/
|
||||
public function insertDisclaimersItem( Group $group ) {
|
||||
$title = Title::newFromText( $this->context->msg( 'disclaimerpage' )
|
||||
->inContentLanguage()->text() );
|
||||
$msg = $this->context->msg( 'disclaimers' );
|
||||
if ( $title && !$msg->isDisabled() ) {
|
||||
$group->insert( 'disclaimers' )
|
||||
->addComponent( $msg->text(), $title->getLocalUrl() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and insert the RecentChanges link
|
||||
* @param Group $group
|
||||
* @throws MWException
|
||||
*/
|
||||
public function insertRecentChanges( Group $group ) {
|
||||
$title = SpecialPage::getTitleFor( 'Recentchanges' );
|
||||
|
||||
$group->insert( 'recentchanges' )
|
||||
->addComponent(
|
||||
$this->context->msg( 'recentchanges' )->escaped(),
|
||||
$title->getLocalURL(),
|
||||
MinervaUI::iconClass( 'recentchanges', 'before' ),
|
||||
[ 'data-event-name' => 'recentchanges' ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and insert the SpecialPages link
|
||||
* @param Group $group
|
||||
* @throws MWException
|
||||
*/
|
||||
public function insertSpecialPages( Group $group ) {
|
||||
$group->insert( 'specialpages' )
|
||||
->addComponent(
|
||||
$this->context->msg( 'specialpages' )->escaped(),
|
||||
SpecialPage::getTitleFor( 'Specialpages' )->getLocalURL(),
|
||||
MinervaUI::iconClass( 'specialpages', 'before' ),
|
||||
[ 'data-event-name' => 'specialpages' ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and insert the CommunityPortal link
|
||||
* @param Group $group
|
||||
* @throws MWException
|
||||
*/
|
||||
public function insertCommunityPortal( Group $group ) {
|
||||
/// placeholder for a follow-up patch @see T216152
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a url to the Special:UserLogin with query parameters
|
||||
*
|
||||
* @param array $query
|
||||
* @return string
|
||||
* @throws MWException
|
||||
*/
|
||||
private function getLoginUrl( $query ) {
|
||||
return SpecialPage::getTitleFor( 'Userlogin' )->getLocalURL( $query );
|
||||
}
|
||||
|
||||
}
|
|
@ -18,19 +18,28 @@
|
|||
* @file
|
||||
*/
|
||||
|
||||
namespace MediaWiki\Minerva;
|
||||
namespace MediaWiki\Minerva\Menu;
|
||||
|
||||
use DomainException;
|
||||
|
||||
/**
|
||||
* Model for a menu that can be presented in a skin.
|
||||
*/
|
||||
class MenuBuilder {
|
||||
class Group {
|
||||
/**
|
||||
* @var MenuEntry[]
|
||||
*/
|
||||
private $entries = [];
|
||||
|
||||
/**
|
||||
* Return entries count
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function hasEntries() {
|
||||
return count( $this->entries ) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all entries represented as plain old PHP arrays.
|
||||
*
|
||||
|
@ -116,3 +125,9 @@ class MenuBuilder {
|
|||
return $entry;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* make sure BlueSpiceMultiUpload and GrowthExperiments use the new class
|
||||
* @TODO remove after updating all extensions that still depend upon MenuBuilder
|
||||
*/
|
||||
class_alias( 'MediaWiki\Minerva\Menu\Group', 'MediaWiki\Minerva\MenuBuilder' );
|
68
includes/menu/Main/AdvancedBuilder.php
Normal file
68
includes/menu/Main/AdvancedBuilder.php
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?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
|
||||
*/
|
||||
|
||||
namespace MediaWiki\Minerva\Menu\Main;
|
||||
|
||||
use FatalError;
|
||||
use Hooks;
|
||||
use MWException;
|
||||
use MediaWiki\Minerva\Menu\Group;
|
||||
|
||||
/**
|
||||
* A menu builder that provides additional menu entries that match
|
||||
* Advanced Mobile Contributions project requirements. This menu
|
||||
* is used when AMC SkinOption flag is set to true.
|
||||
*
|
||||
* @package MediaWiki\Minerva\Menu\Main
|
||||
*/
|
||||
class AdvancedBuilder extends DefaultBuilder {
|
||||
|
||||
/**
|
||||
* @return array|Group[]
|
||||
* @throws FatalError
|
||||
* @throws MWException
|
||||
*/
|
||||
public function getGroups() {
|
||||
return [
|
||||
$this->getDiscoveryTools(),
|
||||
$this->getPersonalTools(),
|
||||
$this->getSiteTools(),
|
||||
$this->getConfigurationTools(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a list of links that have the purpose of discovery in the main navigation menu
|
||||
* @return Group
|
||||
* @throws FatalError
|
||||
* @throws MWException
|
||||
*/
|
||||
public function getSiteTools() {
|
||||
$group = new Group();
|
||||
|
||||
$this->definitions->insertRecentChanges( $group );
|
||||
$this->definitions->insertSpecialPages( $group );
|
||||
$this->definitions->insertCommunityPortal( $group );
|
||||
|
||||
// Allow other extensions to add or override tools
|
||||
Hooks::run( 'MobileMenu', [ 'sitetools', &$group ] );
|
||||
return $group;
|
||||
}
|
||||
}
|
152
includes/menu/Main/DefaultBuilder.php
Normal file
152
includes/menu/Main/DefaultBuilder.php
Normal file
|
@ -0,0 +1,152 @@
|
|||
<?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
|
||||
*/
|
||||
|
||||
namespace MediaWiki\Minerva\Menu\Main;
|
||||
|
||||
use FatalError;
|
||||
use Hooks;
|
||||
use MWException;
|
||||
use User;
|
||||
use MediaWiki\Minerva\Menu\Definitions;
|
||||
use MediaWiki\Minerva\Menu\Group;
|
||||
|
||||
/**
|
||||
* Used to build default (available for everyone by default) main menu
|
||||
*/
|
||||
class DefaultBuilder implements IBuilder {
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $showMobileOptions;
|
||||
|
||||
/**
|
||||
* Currently logged in user
|
||||
* @var User
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* @var Definitions
|
||||
*/
|
||||
protected $definitions;
|
||||
|
||||
/**
|
||||
* Initialize the Default Main Menu builder
|
||||
*
|
||||
* @param bool $showMobileOptions Show MobileOptions instead of Preferences
|
||||
* @param User $user The current user
|
||||
* @param Definitions $definitions A menu items definitions set
|
||||
*/
|
||||
public function __construct( $showMobileOptions, User $user, Definitions $definitions ) {
|
||||
$this->showMobileOptions = $showMobileOptions;
|
||||
$this->user = $user;
|
||||
$this->definitions = $definitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Group[]
|
||||
* @throws FatalError
|
||||
* @throws MWException
|
||||
*/
|
||||
public function getGroups() {
|
||||
return [
|
||||
$this->getDiscoveryTools(),
|
||||
$this->getPersonalTools(),
|
||||
$this->getConfigurationTools(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a list of links that have the purpose of discovery in the main navigation menu
|
||||
* @return Group
|
||||
* @throws FatalError
|
||||
* @throws MWException
|
||||
*/
|
||||
protected function getDiscoveryTools() {
|
||||
$group = new Group();
|
||||
|
||||
$this->definitions->insertHomeItem( $group );
|
||||
$this->definitions->insertRandomItem( $group );
|
||||
$this->definitions->insertNearbyIfSupported( $group );
|
||||
|
||||
// Allow other extensions to add or override tools
|
||||
Hooks::run( 'MobileMenu', [ 'discovery', &$group ] );
|
||||
return $group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the personal tools menu item group.
|
||||
*
|
||||
* ... by adding the Watchlist, Settings, and Log{in,out} menu items in the given order.
|
||||
*
|
||||
* @return Group
|
||||
* @throws FatalError
|
||||
* @throws MWException
|
||||
*/
|
||||
protected function getPersonalTools() {
|
||||
$group = new Group();
|
||||
|
||||
$this->definitions->insertLogInOutMenuItem( $group );
|
||||
|
||||
if ( $this->user->isLoggedIn() ) {
|
||||
$this->definitions->insertWatchlistMenuItem( $group );
|
||||
$this->definitions->insertContributionsMenuItem( $group );
|
||||
}
|
||||
|
||||
// Allow other extensions to add or override tools
|
||||
Hooks::run( 'MobileMenu', [ 'personal', &$group ] );
|
||||
return $group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like <code>SkinMinerva#getDiscoveryTools</code> and <code>#getPersonalTools</code>, create
|
||||
* a group of configuration-related menu items. Currently, only the Settings menu item is in the
|
||||
* group.
|
||||
*
|
||||
* @return Group
|
||||
* @throws MWException
|
||||
*/
|
||||
protected function getConfigurationTools() {
|
||||
$group = new Group();
|
||||
|
||||
$this->showMobileOptions ?
|
||||
$this->definitions->insertMobileOptionsItem( $group ) :
|
||||
$this->definitions->insertPreferencesItem( $group );
|
||||
|
||||
return $group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of sitelinks to add into the main menu footer.
|
||||
* @return Group Collection of site links
|
||||
* @throws MWException
|
||||
*/
|
||||
public function getSiteLinks() {
|
||||
$group = new Group();
|
||||
|
||||
$this->definitions->insertAboutItem( $group );
|
||||
$this->definitions->insertDisclaimersItem( $group );
|
||||
// Allow other extensions to add or override tools
|
||||
Hooks::run( 'MobileMenu', [ 'sitelinks', &$group ] );
|
||||
return $group;
|
||||
}
|
||||
|
||||
}
|
74
includes/menu/Main/Director.php
Normal file
74
includes/menu/Main/Director.php
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?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
|
||||
*/
|
||||
namespace MediaWiki\Minerva\Menu\Main;
|
||||
|
||||
/**
|
||||
* Director responsible for building Main Menu
|
||||
*/
|
||||
final class Director {
|
||||
|
||||
/**
|
||||
* @var IBuilder
|
||||
*/
|
||||
private $builder;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $menuData;
|
||||
|
||||
/**
|
||||
* Director responsible for Main Menu building
|
||||
*
|
||||
* @param IBuilder $builder
|
||||
*/
|
||||
public function __construct( IBuilder $builder ) {
|
||||
$this->builder = $builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a data representation of the main menus
|
||||
* @return array
|
||||
*/
|
||||
public function getMenuData() {
|
||||
if ( $this->menuData === null ) {
|
||||
$this->menuData = $this->buildMenu();
|
||||
}
|
||||
return $this->menuData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the menu data array that can be passed to views/javascript
|
||||
* @return array
|
||||
*/
|
||||
private function buildMenu() {
|
||||
$menuData = [
|
||||
'groups' => [],
|
||||
'sitelinks' => $this->builder->getSiteLinks()->getEntries()
|
||||
];
|
||||
foreach ( $this->builder->getGroups() as $group ) {
|
||||
if ( $group->hasEntries() ) {
|
||||
$menuData['groups'][] = $group->getEntries();
|
||||
}
|
||||
}
|
||||
return $menuData;
|
||||
}
|
||||
|
||||
}
|
36
includes/menu/Main/IBuilder.php
Normal file
36
includes/menu/Main/IBuilder.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?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
|
||||
*/
|
||||
|
||||
namespace MediaWiki\Minerva\Menu\Main;
|
||||
|
||||
use MediaWiki\Minerva\Menu\Group;
|
||||
|
||||
interface IBuilder {
|
||||
|
||||
/**
|
||||
* @return Group[]
|
||||
*/
|
||||
public function getGroups();
|
||||
|
||||
/**
|
||||
* @return Group
|
||||
*/
|
||||
public function getSiteLinks();
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
namespace MediaWiki\Minerva;
|
||||
namespace MediaWiki\Minerva\Menu;
|
||||
|
||||
/**
|
||||
* Model for a menu entry.
|
|
@ -18,9 +18,10 @@
|
|||
* @file
|
||||
*/
|
||||
|
||||
use MediaWiki\Minerva\MenuBuilder;
|
||||
use MediaWiki\Minerva\SkinOptions;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Minerva\Menu\Main\Director as MainMenuDirector;
|
||||
use MediaWiki\Minerva\SkinOptions;
|
||||
use MediaWiki\Minerva\SkinUserPageHelper;
|
||||
|
||||
/**
|
||||
* Minerva: Born from the godhead of Jupiter with weapons!
|
||||
|
@ -52,9 +53,29 @@ class SkinMinerva extends SkinTemplate {
|
|||
$this->skinOptions = MediaWikiServices::getInstance()->getService( 'Minerva.SkinOptions' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initalized main menu. Please use getter.
|
||||
* @return MainMenuDirector
|
||||
*
|
||||
*/
|
||||
private $mainMenu;
|
||||
|
||||
/**
|
||||
* Build the Main Menu Director by passing the skin options
|
||||
*
|
||||
* @return MainMenuDirector
|
||||
*/
|
||||
protected function getMainMenu() {
|
||||
if ( !$this->mainMenu ) {
|
||||
$this->mainMenu = MediaWikiServices::getInstance()->getService( 'Minerva.Menu.MainDirector' );
|
||||
}
|
||||
return $this->mainMenu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the site name for the footer, either as a text or <img> tag
|
||||
* @return string
|
||||
* @throws ConfigException
|
||||
*/
|
||||
public function getSitename() {
|
||||
$config = $this->getConfig();
|
||||
|
@ -118,7 +139,7 @@ class SkinMinerva extends SkinTemplate {
|
|||
$tpl->set( 'unstyledContent', $out->getProperty( 'unstyledContent' ) );
|
||||
|
||||
// Set the links for the main menu
|
||||
$tpl->set( 'menu_data', $this->getMenuData() );
|
||||
$tpl->set( 'menu_data', $this->getMainMenu()->getMenuData() );
|
||||
|
||||
// Set the links for page secondary actions
|
||||
$tpl->set( 'secondary_actions', $this->getSecondaryActions( $tpl ) );
|
||||
|
@ -428,122 +449,6 @@ class SkinMinerva extends SkinTemplate {
|
|||
] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the Contributions menu item into the menu.
|
||||
*
|
||||
* @param MenuBuilder $menu
|
||||
* @param User $user The user to whom the contributions belong
|
||||
*/
|
||||
private function insertContributionsMenuItem( MenuBuilder $menu, User $user ) {
|
||||
$menu->insert( 'contribs' )
|
||||
->addComponent(
|
||||
$this->msg( 'mobile-frontend-main-menu-contributions' )->escaped(),
|
||||
SpecialPage::getTitleFor( 'Contributions', $user->getName() )->getLocalUrl(),
|
||||
MinervaUI::iconClass( 'contributions', 'before' ),
|
||||
[ 'data-event-name' => 'contributions' ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the Watchlist menu item into the menu for a logged in user
|
||||
*
|
||||
* @param MenuBuilder $menu
|
||||
* @param User $user that must be logged in
|
||||
*/
|
||||
protected function insertWatchlistMenuItem( MenuBuilder $menu, User $user ) {
|
||||
$watchTitle = SpecialPage::getTitleFor( 'Watchlist' );
|
||||
|
||||
// Watchlist link
|
||||
$watchlistQuery = [];
|
||||
// Avoid fatal when MobileFrontend not available (T171241)
|
||||
if ( class_exists( 'SpecialMobileWatchlist' ) ) {
|
||||
$view = $user->getOption( SpecialMobileWatchlist::VIEW_OPTION_NAME, false );
|
||||
$filter = $user->getOption( SpecialMobileWatchlist::FILTER_OPTION_NAME, false );
|
||||
if ( $view ) {
|
||||
$watchlistQuery['watchlistview'] = $view;
|
||||
}
|
||||
if ( $filter && $view === 'feed' ) {
|
||||
$watchlistQuery['filter'] = $filter;
|
||||
}
|
||||
}
|
||||
|
||||
$menu->insert( 'watchlist' )
|
||||
->addComponent(
|
||||
$this->msg( 'mobile-frontend-main-menu-watchlist' )->escaped(),
|
||||
$watchTitle->getLocalURL( $watchlistQuery ),
|
||||
MinervaUI::iconClass( 'watchlist', 'before' ),
|
||||
[ 'data-event-name' => 'watchlist' ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user is using a mobile device (or the UA presents itself as a mobile device), then the
|
||||
* Settings menu item is inserted into the menu; otherwise the Preferences menu item is inserted.
|
||||
*
|
||||
* @param MenuBuilder $menu
|
||||
*/
|
||||
protected function insertSettingsMenuItem( MenuBuilder $menu ) {
|
||||
$returnToTitle = $this->getTitle()->getPrefixedText();
|
||||
|
||||
// Links specifically for mobile mode
|
||||
if ( $this->skinOptions->get( SkinOptions::OPTION_MOBILE_OPTIONS ) ) {
|
||||
// Settings link
|
||||
$menu->insert( 'settings' )
|
||||
->addComponent(
|
||||
$this->msg( 'mobile-frontend-main-menu-settings' )->escaped(),
|
||||
SpecialPage::getTitleFor( 'MobileOptions' )->
|
||||
getLocalURL( [ 'returnto' => $returnToTitle ] ),
|
||||
MinervaUI::iconClass( 'settings', 'before' ),
|
||||
[ 'data-event-name' => 'settings' ]
|
||||
);
|
||||
|
||||
// Links specifically for desktop mode
|
||||
} else {
|
||||
|
||||
// Preferences link
|
||||
$menu->insert( 'preferences' )
|
||||
->addComponent(
|
||||
$this->msg( 'preferences' )->escaped(),
|
||||
SpecialPage::getTitleFor( 'Preferences' )->getLocalURL(),
|
||||
MinervaUI::iconClass( 'settings', 'before' ),
|
||||
[ 'data-event-name' => 'preferences' ]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the personal tools menu item group.
|
||||
*
|
||||
* ... by adding the Watchlist, Settings, and Log{in,out} menu items in the given order.
|
||||
*
|
||||
* @param MenuBuilder $menu
|
||||
*/
|
||||
protected function buildPersonalTools( MenuBuilder $menu ) {
|
||||
$this->insertLogInOutMenuItem( $menu );
|
||||
|
||||
$user = $this->getUser();
|
||||
|
||||
if ( $user->isLoggedIn() ) {
|
||||
$this->insertWatchlistMenuItem( $menu, $user );
|
||||
$this->insertContributionsMenuItem( $menu, $user );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares and returns urls and links personal to the given user
|
||||
* @return array
|
||||
*/
|
||||
protected function getPersonalTools() {
|
||||
$menu = new MenuBuilder();
|
||||
|
||||
$this->buildPersonalTools( $menu );
|
||||
|
||||
// Allow other extensions to add or override tools
|
||||
Hooks::run( 'MobileMenu', [ 'personal', &$menu ] );
|
||||
return $menu->getEntries();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrites the language list so that it cannot be contaminated by other extensions with things
|
||||
* other than languages
|
||||
|
@ -561,67 +466,6 @@ class SkinMinerva extends SkinTemplate {
|
|||
$tpl->set( 'language_urls', $language_urls );
|
||||
}
|
||||
|
||||
/**
|
||||
* Like <code>SkinMinerva#getDiscoveryTools</code> and <code>#getPersonalTools</code>, create
|
||||
* a group of configuration-related menu items. Currently, only the Settings menu item is in the
|
||||
* group.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getConfigurationTools() {
|
||||
$menu = new MenuBuilder();
|
||||
|
||||
$this->insertSettingsMenuItem( $menu );
|
||||
|
||||
return $menu->getEntries();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a list of links that have the purpose of discovery in the main navigation menu
|
||||
* @return array
|
||||
*/
|
||||
protected function getDiscoveryTools() {
|
||||
$config = $this->getConfig();
|
||||
$menu = new MenuBuilder();
|
||||
$factory = MediaWikiServices::getInstance()->getSpecialPageFactory();
|
||||
|
||||
// Home link
|
||||
$menu->insert( 'home' )
|
||||
->addComponent(
|
||||
$this->msg( 'mobile-frontend-home-button' )->escaped(),
|
||||
Title::newMainPage()->getLocalURL(),
|
||||
MinervaUI::iconClass( 'home', 'before' ),
|
||||
[ 'data-event-name' => 'home' ]
|
||||
);
|
||||
|
||||
// Random link
|
||||
$menu->insert( 'random' )
|
||||
->addComponent(
|
||||
$this->msg( 'mobile-frontend-random-button' )->escaped(),
|
||||
SpecialPage::getTitleFor( 'Randompage' )->getLocalURL() . '#/random',
|
||||
MinervaUI::iconClass( 'random', 'before' ),
|
||||
[
|
||||
'id' => 'randomButton',
|
||||
'data-event-name' => 'random',
|
||||
]
|
||||
);
|
||||
|
||||
// Nearby link (if supported)
|
||||
if ( $factory->exists( 'Nearby' ) ) {
|
||||
$menu->insert( 'nearby', $isJSOnly = true )
|
||||
->addComponent(
|
||||
$this->msg( 'mobile-frontend-main-menu-nearby' )->escaped(),
|
||||
SpecialPage::getTitleFor( 'Nearby' )->getLocalURL(),
|
||||
MinervaUI::iconClass( 'nearby', 'before', 'nearby' ),
|
||||
[ 'data-event-name' => 'nearby' ]
|
||||
);
|
||||
}
|
||||
|
||||
// Allow other extensions to add or override tools
|
||||
Hooks::run( 'MobileMenu', [ 'discovery', &$menu ] );
|
||||
return $menu->getEntries();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a url to the Special:UserLogin with query parameters
|
||||
* @param array $query
|
||||
|
@ -631,64 +475,6 @@ class SkinMinerva extends SkinTemplate {
|
|||
return SpecialPage::getTitleFor( 'Userlogin' )->getLocalURL( $query );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a login or logout button
|
||||
*
|
||||
* @param MenuBuilder $menu
|
||||
*/
|
||||
protected function insertLogInOutMenuItem( MenuBuilder $menu ) {
|
||||
$query = [];
|
||||
$returntoquery = [];
|
||||
|
||||
if ( !$this->getRequest()->wasPosted() ) {
|
||||
$returntoquery = $this->getRequest()->getValues();
|
||||
unset( $returntoquery['title'] );
|
||||
unset( $returntoquery['returnto'] );
|
||||
unset( $returntoquery['returntoquery'] );
|
||||
}
|
||||
$title = $this->getTitle();
|
||||
// Don't ever redirect back to the login page (bug 55379)
|
||||
if ( !$title->isSpecial( 'Userlogin' ) ) {
|
||||
$query[ 'returnto' ] = $title->getPrefixedText();
|
||||
}
|
||||
|
||||
$user = $this->getUser();
|
||||
if ( $user->isLoggedIn() ) {
|
||||
if ( !empty( $returntoquery ) ) {
|
||||
$query[ 'returntoquery' ] = wfArrayToCgi( $returntoquery );
|
||||
}
|
||||
$url = SpecialPage::getTitleFor( 'Userlogout' )->getLocalURL( $query );
|
||||
$username = $user->getName();
|
||||
|
||||
$menu->insert( 'auth', false )
|
||||
->addComponent(
|
||||
$username,
|
||||
Title::newFromText( $username, NS_USER )->getLocalURL(),
|
||||
MinervaUI::iconClass( 'profile', 'before', 'truncated-text primary-action' ),
|
||||
[ 'data-event-name' => 'profile' ]
|
||||
)
|
||||
->addComponent(
|
||||
$this->msg( 'mobile-frontend-main-menu-logout' )->escaped(),
|
||||
$url,
|
||||
MinervaUI::iconClass(
|
||||
'logout', 'element', 'secondary-action truncated-text' ),
|
||||
[ 'data-event-name' => 'logout' ]
|
||||
);
|
||||
} else {
|
||||
// unset campaign on login link so as not to interfere with A/B tests
|
||||
unset( $returntoquery['campaign'] );
|
||||
$query[ 'returntoquery' ] = wfArrayToCgi( $returntoquery );
|
||||
$url = $this->getLoginUrl( $query );
|
||||
$menu->insert( 'auth', false )
|
||||
->addComponent(
|
||||
$this->msg( 'mobile-frontend-main-menu-login' )->escaped(),
|
||||
$url,
|
||||
MinervaUI::iconClass( 'login', 'before' ),
|
||||
[ 'data-event-name' => 'login' ]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a history link which describes author and relative time of last edit
|
||||
* @param Title $title The Title object of the page being viewed
|
||||
|
@ -930,34 +716,6 @@ class SkinMinerva extends SkinTemplate {
|
|||
$tpl->set( 'internalBanner', '' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of sitelinks to add into the main menu footer.
|
||||
* @return array Array of site links
|
||||
*/
|
||||
protected function getSiteLinks() {
|
||||
$menu = new MenuBuilder();
|
||||
|
||||
// About link
|
||||
$title = Title::newFromText( $this->msg( 'aboutpage' )->inContentLanguage()->text() );
|
||||
$msg = $this->msg( 'aboutsite' );
|
||||
if ( $title && !$msg->isDisabled() ) {
|
||||
$menu->insert( 'about' )
|
||||
->addComponent( $msg->text(), $title->getLocalURL() );
|
||||
}
|
||||
|
||||
// Disclaimers link
|
||||
$title = Title::newFromText( $this->msg( 'disclaimerpage' )->inContentLanguage()->text() );
|
||||
$msg = $this->msg( 'disclaimers' );
|
||||
if ( $title && !$msg->isDisabled() ) {
|
||||
$menu->insert( 'disclaimers' )
|
||||
->addComponent( $msg->text(), $title->getLocalURL() );
|
||||
}
|
||||
|
||||
// Allow other extensions to add or override tools
|
||||
Hooks::run( 'MobileMenu', [ 'sitelinks', &$menu ] );
|
||||
return $menu->getEntries();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with details for a language button.
|
||||
* @return array
|
||||
|
@ -1232,23 +990,6 @@ class SkinMinerva extends SkinTemplate {
|
|||
&& $contentHandler->supportsDirectApiEditing();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a data representation of the main menus
|
||||
* @return array
|
||||
*/
|
||||
protected function getMenuData() {
|
||||
$data = [
|
||||
'groups' => [
|
||||
$this->getDiscoveryTools(),
|
||||
$this->getPersonalTools(),
|
||||
$this->getConfigurationTools(),
|
||||
],
|
||||
'sitelinks' => $this->getSiteLinks(),
|
||||
];
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of config variables that should be added only to this skin
|
||||
* for use in JavaScript.
|
||||
|
@ -1258,7 +999,7 @@ class SkinMinerva extends SkinTemplate {
|
|||
$vars = [
|
||||
'wgMinervaFeatures' => $this->skinOptions->getAll(),
|
||||
'wgMinervaDownloadNamespaces' => $this->getConfig()->get( 'MinervaDownloadNamespaces' ),
|
||||
'wgMinervaMenuData' => $this->getMenuData(),
|
||||
'wgMinervaMenuData' => $this->getMainMenu()->getMenuData(),
|
||||
];
|
||||
|
||||
return $vars;
|
||||
|
|
1
resources/skins.minerva.mainMenu.icons/recentchanges.svg
Normal file
1
resources/skins.minerva.mainMenu.icons/recentchanges.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="21" height="17" xmlns="http://www.w3.org/2000/svg"><path d="M0 16.625h21v-4.156H0v4.156zm2.1-3.117h2.1v2.078H2.1v-2.078zM0 0v4.156h21V0H0zm4.2 3.117H2.1V1.04h2.1v2.078zM0 10.391h21V6.234H0v4.157zm2.1-3.118h2.1v2.079H2.1V7.273z" fill="#4A4F53"/></svg>
|
After Width: | Height: | Size: 262 B |
1
resources/skins.minerva.mainMenu.icons/specialpages.svg
Normal file
1
resources/skins.minerva.mainMenu.icons/specialpages.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="22" height="18" xmlns="http://www.w3.org/2000/svg"><path d="M19.8 2.177H11L8.8 0H2.2C.99 0 0 .98 0 2.177V15.24c0 1.197.99 2.177 2.2 2.177h17.6c1.21 0 2.2-.98 2.2-2.177V4.354c0-1.197-.99-2.177-2.2-2.177zm-2.266 11.974L14.3 12.279l-3.234 1.872.858-3.625-2.849-2.438 3.751-.316L14.3 4.354l1.474 3.418 3.751.316-2.849 2.438.858 3.625z" fill="#4A4F53"/></svg>
|
After Width: | Height: | Size: 366 B |
11
skin.json
11
skin.json
|
@ -67,14 +67,17 @@
|
|||
"ValidSkinNames": {
|
||||
"minerva": "MinervaNeue"
|
||||
},
|
||||
"AutoloadNamespaces": {
|
||||
"MediaWiki\\Minerva\\Menu\\": "includes/menu/"
|
||||
},
|
||||
"AutoloadClasses": {
|
||||
"MinervaUI": "includes/MinervaUI.php",
|
||||
"MinervaHooks": "includes/MinervaHooks.php",
|
||||
"MinervaTemplate": "includes/skins/MinervaTemplate.php",
|
||||
"SkinMinerva": "includes/skins/SkinMinerva.php",
|
||||
"SkinMinervaNeue": "includes/skins/SkinMinerva.php",
|
||||
"MediaWiki\\Minerva\\MenuBuilder": "includes/skins/MenuBuilder.php",
|
||||
"MediaWiki\\Minerva\\MenuEntry": "includes/skins/MenuEntry.php",
|
||||
"MediaWiki\\Minerva\\Menu\\Group": "includes/menu/Group.php",
|
||||
"MediaWiki\\Minerva\\MenuBuilder": "includes/menu/Group.php",
|
||||
"MediaWiki\\Minerva\\ResourceLoaderLessVarFileModule": "includes/ResourceLoaderLessVarFileModule.php",
|
||||
"MediaWiki\\Minerva\\SkinOptions": "includes/SkinOptions.php",
|
||||
"MediaWiki\\Minerva\\SkinUserPageHelper": "includes/skins/SkinUserPageHelper.php"
|
||||
|
@ -341,7 +344,9 @@
|
|||
"random": "resources/skins.minerva.mainMenu.icons/random.svg",
|
||||
"settings": "resources/skins.minerva.mainMenu.icons/settings.svg",
|
||||
"watchlist": "resources/skins.minerva.mainMenu.icons/watchlist.svg",
|
||||
"contributions": "resources/skins.minerva.mainMenu.icons/contributions.svg"
|
||||
"contributions": "resources/skins.minerva.mainMenu.icons/contributions.svg",
|
||||
"recentchanges": "resources/skins.minerva.mainMenu.icons/recentchanges.svg",
|
||||
"specialpages": "resources/skins.minerva.mainMenu.icons/specialpages.svg"
|
||||
}
|
||||
},
|
||||
"skins.minerva.mainMenu.styles": {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\MediaWiki\Minerva;
|
||||
namespace Tests\MediaWiki\Minerva\Menu;
|
||||
|
||||
use MediaWiki\Minerva\MenuBuilder;
|
||||
use MediaWiki\Minerva\MenuEntry;
|
||||
use MediaWiki\Minerva\Menu\Group;
|
||||
|
||||
/**
|
||||
* @group MinervaNeue
|
||||
* @coversDefaultClass \MediaWiki\Minerva\Menu\Group
|
||||
*/
|
||||
class MenuBuilderTest extends \PHPUnit\Framework\TestCase {
|
||||
class GroupTest extends \MediaWikiTestCase {
|
||||
private $homeComponent = [
|
||||
'text' => 'Home',
|
||||
'href' => '/Main_page',
|
||||
|
@ -23,22 +23,22 @@ class MenuBuilderTest extends \PHPUnit\Framework\TestCase {
|
|||
];
|
||||
|
||||
/**
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::getEntries
|
||||
* @covers ::getEntries
|
||||
*/
|
||||
public function testItShouldntHaveEntriesByDefault() {
|
||||
$menu = new MenuBuilder();
|
||||
$menu = new Group();
|
||||
|
||||
$this->assertEmpty( $menu->getEntries() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::insert
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::search
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::getEntries
|
||||
* @covers \MediaWiki\Minerva\MenuEntry::addComponent
|
||||
* @covers ::insert
|
||||
* @covers ::search
|
||||
* @covers ::getEntries
|
||||
* @covers \MediaWiki\Minerva\Menu\MenuEntry::addComponent
|
||||
*/
|
||||
public function testInsertingAnEntry() {
|
||||
$menu = new MenuBuilder();
|
||||
$menu = new Group();
|
||||
$menu->insert( 'home' )
|
||||
->addComponent(
|
||||
$this->homeComponent['text'],
|
||||
|
@ -60,13 +60,13 @@ class MenuBuilderTest extends \PHPUnit\Framework\TestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::insert
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::search
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::getEntries
|
||||
* @covers \MediaWiki\Minerva\MenuEntry::addComponent
|
||||
* @covers ::insert
|
||||
* @covers ::search
|
||||
* @covers ::getEntries
|
||||
* @covers \MediaWiki\Minerva\Menu\MenuEntry::addComponent
|
||||
*/
|
||||
public function testInsertingAnEntryAfterAnother() {
|
||||
$menu = new MenuBuilder();
|
||||
$menu = new Group();
|
||||
$menu->insert( 'home' )
|
||||
->addComponent(
|
||||
$this->homeComponent['text'],
|
||||
|
@ -113,12 +113,12 @@ class MenuBuilderTest extends \PHPUnit\Framework\TestCase {
|
|||
/**
|
||||
* @expectedException \DomainException
|
||||
* @expectedExceptionMessage The "home" entry doesn't exist.
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::insertAfter
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::search
|
||||
* @covers \MediaWiki\Minerva\MenuEntry::addComponent
|
||||
* @covers ::insertAfter
|
||||
* @covers ::search
|
||||
* @covers \MediaWiki\Minerva\Menu\MenuEntry::addComponent
|
||||
*/
|
||||
public function testInsertAfterWhenTargetEntryDoesntExist() {
|
||||
$menu = new MenuBuilder();
|
||||
$menu = new Group();
|
||||
$menu->insertAfter( 'home', 'nearby' )
|
||||
->addComponent(
|
||||
$this->nearbyComponent['text'],
|
||||
|
@ -130,10 +130,10 @@ class MenuBuilderTest extends \PHPUnit\Framework\TestCase {
|
|||
/**
|
||||
* @expectedException \DomainException
|
||||
* @expectedExceptionMessage The "car" entry already exists.
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::insertAfter
|
||||
* @covers ::insertAfter
|
||||
*/
|
||||
public function testInsertAfterWithAnEntryWithAnExistingName() {
|
||||
$menu = new MenuBuilder();
|
||||
$menu = new Group();
|
||||
$menu->insert( 'home' );
|
||||
$menu->insert( 'car' );
|
||||
$menu->insertAfter( 'home', 'car' );
|
||||
|
@ -142,20 +142,20 @@ class MenuBuilderTest extends \PHPUnit\Framework\TestCase {
|
|||
/**
|
||||
* @expectedException \DomainException
|
||||
* @expectedExceptionMessage The "home" entry already exists.
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::insert
|
||||
* @covers ::insert
|
||||
*/
|
||||
public function testInsertingAnEntryWithAnExistingName() {
|
||||
$menu = new MenuBuilder();
|
||||
$menu = new Group();
|
||||
$menu->insert( 'home' );
|
||||
$menu->insert( 'home' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::insert
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::insertAfter
|
||||
* @covers ::insert
|
||||
* @covers ::insertAfter
|
||||
*/
|
||||
public function testInsertingAnEntryAfterAnotherOne() {
|
||||
$menu = new MenuBuilder();
|
||||
$menu = new Group();
|
||||
$menu->insert( 'first' );
|
||||
$menu->insert( 'last' );
|
||||
$menu->insertAfter( 'first', 'middle' );
|
||||
|
@ -167,9 +167,9 @@ class MenuBuilderTest extends \PHPUnit\Framework\TestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::insert
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::getEntries
|
||||
* @covers \MediaWiki\Minerva\MenuEntry::addComponent
|
||||
* @covers ::insert
|
||||
* @covers ::getEntries
|
||||
* @covers \MediaWiki\Minerva\Menu\MenuEntry::addComponent
|
||||
*/
|
||||
public function testinsertingAnEntryWithMultipleComponents() {
|
||||
$authLoginComponent = [
|
||||
|
@ -185,7 +185,7 @@ class MenuBuilderTest extends \PHPUnit\Framework\TestCase {
|
|||
'mw-ui-icon mw-ui-icon-element secondary-logout secondary-action truncated-text',
|
||||
];
|
||||
|
||||
$menu = new MenuBuilder();
|
||||
$menu = new Group();
|
||||
$menu->insert( 'auth' )
|
||||
->addComponent(
|
||||
$authLoginComponent['text'],
|
||||
|
@ -212,12 +212,12 @@ class MenuBuilderTest extends \PHPUnit\Framework\TestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::insert
|
||||
* @covers \MediaWiki\Minerva\MenuBuilder::getEntries
|
||||
* @covers \MediaWiki\Minerva\MenuEntry::addComponent
|
||||
* @covers ::insert
|
||||
* @covers ::getEntries
|
||||
* @covers \MediaWiki\Minerva\Menu\MenuEntry::addComponent
|
||||
*/
|
||||
public function testInsertingAJavascriptOnlyEntry() {
|
||||
$menu = new MenuBuilder();
|
||||
$menu = new Group();
|
||||
$menu->insert( 'nearby', $isJSOnly = true )
|
||||
->addComponent(
|
||||
$this->nearbyComponent['text'],
|
||||
|
@ -236,18 +236,4 @@ class MenuBuilderTest extends \PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals( $expectedEntries, $menu->getEntries() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \MediaWiki\Minerva\MenuEntry::__construct
|
||||
* @covers \MediaWiki\Minerva\MenuEntry::getName()
|
||||
* @covers \MediaWiki\Minerva\MenuEntry::isJSOnly()
|
||||
* @covers \MediaWiki\Minerva\MenuEntry::getComponents()
|
||||
*/
|
||||
public function testMenuEntryConstruction() {
|
||||
$name = 'test';
|
||||
$isJSOnly = true;
|
||||
$entry = new MenuEntry( $name, $isJSOnly );
|
||||
$this->assertSame( $name, $entry->getName() );
|
||||
$this->assertSame( $isJSOnly, $entry->isJSOnly() );
|
||||
$this->assertSame( [], $entry->getComponents() );
|
||||
}
|
||||
}
|
27
tests/phpunit/menu/MenuEntryTest.php
Normal file
27
tests/phpunit/menu/MenuEntryTest.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\MediaWiki\Minerva\Menu;
|
||||
|
||||
use MediaWiki\Minerva\Menu\MenuEntry;
|
||||
|
||||
/**
|
||||
* @group MinervaNeue
|
||||
* @coversDefaultClass \MediaWiki\Minerva\Menu\MenuEntry
|
||||
*/
|
||||
class MenuEntryTest extends \MediaWikiTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::__construct
|
||||
* @covers ::getName()
|
||||
* @covers ::isJSOnly()
|
||||
* @covers ::getComponents()
|
||||
*/
|
||||
public function testMenuEntryConstruction() {
|
||||
$name = 'test';
|
||||
$isJSOnly = true;
|
||||
$entry = new MenuEntry( $name, $isJSOnly );
|
||||
$this->assertSame( $name, $entry->getName() );
|
||||
$this->assertSame( $isJSOnly, $entry->isJSOnly() );
|
||||
$this->assertSame( [], $entry->getComponents() );
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue