2017-07-12 15:12:40 +00:00
|
|
|
<?php
|
|
|
|
/**
|
2018-04-15 23:21:12 +00:00
|
|
|
* 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
|
2017-07-12 15:12:40 +00:00
|
|
|
*/
|
|
|
|
|
2022-02-15 18:40:10 +00:00
|
|
|
namespace MediaWiki\Minerva;
|
|
|
|
|
2022-08-21 17:03:43 +00:00
|
|
|
use ChangesList;
|
|
|
|
use ChangesListFilterGroup;
|
2023-09-29 21:55:29 +00:00
|
|
|
use DifferenceEngine;
|
2022-02-15 18:40:10 +00:00
|
|
|
use ExtensionRegistry;
|
2024-01-06 15:31:38 +00:00
|
|
|
use MediaWiki\Config\Config;
|
2023-09-29 21:55:29 +00:00
|
|
|
use MediaWiki\Diff\Hook\DifferenceEngineViewHeaderHook;
|
2022-08-21 17:03:43 +00:00
|
|
|
use MediaWiki\Hook\FetchChangesListHook;
|
2024-03-03 14:40:39 +00:00
|
|
|
use MediaWiki\Hook\PreferencesGetLayoutHook;
|
2022-08-21 17:03:43 +00:00
|
|
|
use MediaWiki\Hook\UserLogoutCompleteHook;
|
2024-01-06 15:31:38 +00:00
|
|
|
use MediaWiki\Html\Html;
|
2022-03-04 16:40:54 +00:00
|
|
|
use MediaWiki\Minerva\Skins\SkinMinerva;
|
2024-05-19 12:45:56 +00:00
|
|
|
use MediaWiki\Output\Hook\OutputPageBodyAttributesHook;
|
2024-01-06 15:31:38 +00:00
|
|
|
use MediaWiki\Output\OutputPage;
|
2024-02-01 23:05:55 +00:00
|
|
|
use MediaWiki\Preferences\Hook\GetPreferencesHook;
|
2022-08-21 17:03:43 +00:00
|
|
|
use MediaWiki\ResourceLoader\Context;
|
|
|
|
use MediaWiki\ResourceLoader\Hook\ResourceLoaderGetConfigVarsHook;
|
|
|
|
use MediaWiki\ResourceLoader\Hook\ResourceLoaderRegisterModulesHook;
|
|
|
|
use MediaWiki\ResourceLoader\ResourceLoader;
|
|
|
|
use MediaWiki\Skins\Hook\SkinPageReadyConfigHook;
|
|
|
|
use MediaWiki\SpecialPage\Hook\SpecialPageBeforeExecuteHook;
|
2024-01-06 15:31:38 +00:00
|
|
|
use MediaWiki\SpecialPage\SpecialPage;
|
2024-02-26 19:47:57 +00:00
|
|
|
use MediaWiki\User\Options\UserOptionsLookup;
|
2024-01-06 15:31:38 +00:00
|
|
|
use MediaWiki\User\User;
|
2024-03-12 19:10:35 +00:00
|
|
|
use MobileContext;
|
2022-02-15 18:40:10 +00:00
|
|
|
use OldChangesList;
|
|
|
|
use Skin;
|
2024-02-26 19:47:57 +00:00
|
|
|
use Wikimedia\Rdbms\ConfiguredReadOnlyMode;
|
2018-04-15 23:21:12 +00:00
|
|
|
|
2017-07-12 15:12:40 +00:00
|
|
|
/**
|
|
|
|
* Hook handlers for Minerva skin.
|
|
|
|
*
|
|
|
|
* Hook handler method names should be in the form of:
|
|
|
|
* on<HookName>()
|
|
|
|
*/
|
2022-08-21 17:03:43 +00:00
|
|
|
class Hooks implements
|
2023-09-29 21:55:29 +00:00
|
|
|
DifferenceEngineViewHeaderHook,
|
2022-08-21 17:03:43 +00:00
|
|
|
FetchChangesListHook,
|
2024-02-01 23:05:55 +00:00
|
|
|
GetPreferencesHook,
|
2022-08-21 17:03:43 +00:00
|
|
|
OutputPageBodyAttributesHook,
|
2024-03-03 14:40:39 +00:00
|
|
|
PreferencesGetLayoutHook,
|
2022-08-21 17:03:43 +00:00
|
|
|
ResourceLoaderGetConfigVarsHook,
|
|
|
|
ResourceLoaderRegisterModulesHook,
|
|
|
|
SkinPageReadyConfigHook,
|
|
|
|
SpecialPageBeforeExecuteHook,
|
|
|
|
UserLogoutCompleteHook
|
|
|
|
{
|
2023-08-15 15:02:31 +00:00
|
|
|
public const FEATURE_OVERFLOW_PAGE_ACTIONS = 'MinervaOverflowInPageActions';
|
2019-04-04 21:20:39 +00:00
|
|
|
|
2024-02-26 19:47:57 +00:00
|
|
|
private ConfiguredReadOnlyMode $configuredReadOnlyMode;
|
2024-03-12 19:35:14 +00:00
|
|
|
private SkinOptions $skinOptions;
|
2024-02-26 19:47:57 +00:00
|
|
|
private UserOptionsLookup $userOptionsLookup;
|
2024-03-12 19:10:35 +00:00
|
|
|
private ?MobileContext $mobileContext;
|
2024-02-26 19:47:57 +00:00
|
|
|
|
|
|
|
public function __construct(
|
|
|
|
ConfiguredReadOnlyMode $configuredReadOnlyMode,
|
2024-03-12 19:35:14 +00:00
|
|
|
SkinOptions $skinOptions,
|
2024-03-12 19:10:35 +00:00
|
|
|
UserOptionsLookup $userOptionsLookup,
|
|
|
|
?MobileContext $mobileContext
|
2024-02-26 19:47:57 +00:00
|
|
|
) {
|
|
|
|
$this->configuredReadOnlyMode = $configuredReadOnlyMode;
|
2024-03-12 19:35:14 +00:00
|
|
|
$this->skinOptions = $skinOptions;
|
2024-02-26 19:47:57 +00:00
|
|
|
$this->userOptionsLookup = $userOptionsLookup;
|
2024-03-12 19:10:35 +00:00
|
|
|
$this->mobileContext = $mobileContext;
|
2024-02-26 19:47:57 +00:00
|
|
|
}
|
|
|
|
|
2019-12-18 21:15:26 +00:00
|
|
|
/**
|
|
|
|
* ResourceLoaderRegisterModules hook handler.
|
|
|
|
*
|
|
|
|
* Registers:
|
|
|
|
*
|
|
|
|
* * EventLogging schema modules, if the EventLogging extension is loaded;
|
|
|
|
* * Modules for the Visual Editor overlay, if the VisualEditor extension is loaded; and
|
|
|
|
* * Modules for the notifications overlay, if the Echo extension is loaded.
|
|
|
|
*
|
|
|
|
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ResourceLoaderRegisterModules
|
|
|
|
*
|
2022-02-15 18:40:10 +00:00
|
|
|
* @param ResourceLoader $resourceLoader
|
2019-12-18 21:15:26 +00:00
|
|
|
*/
|
2022-08-21 17:03:43 +00:00
|
|
|
public function onResourceLoaderRegisterModules( ResourceLoader $resourceLoader ): void {
|
2019-12-18 21:15:26 +00:00
|
|
|
if ( !ExtensionRegistry::getInstance()->isLoaded( 'MobileFrontend' ) ) {
|
|
|
|
$resourceLoader->register( [
|
|
|
|
'mobile.startup' => [
|
|
|
|
'dependencies' => [ 'mediawiki.searchSuggest' ],
|
|
|
|
'localBasePath' => dirname( __DIR__ ),
|
|
|
|
'remoteExtPath' => 'Minerva',
|
|
|
|
'scripts' => 'resources/mobile.startup.stub.js',
|
|
|
|
]
|
|
|
|
] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-01 23:05:55 +00:00
|
|
|
/**
|
|
|
|
* Adds Minerva-specific user preferences that can only be accessed via API
|
|
|
|
*
|
|
|
|
* @param User $user user whose preferences are being modified
|
|
|
|
* @param array[] &$prefs preferences description array, to be fed to a HTMLForm object
|
|
|
|
*/
|
|
|
|
public function onGetPreferences( $user, &$prefs ): void {
|
|
|
|
$minervaPrefs = [
|
2024-03-18 19:14:23 +00:00
|
|
|
'minerva-theme' => [
|
2024-02-01 23:05:55 +00:00
|
|
|
'type' => 'api'
|
|
|
|
],
|
|
|
|
];
|
|
|
|
|
|
|
|
$prefs += $minervaPrefs;
|
|
|
|
}
|
|
|
|
|
2022-10-12 13:37:28 +00:00
|
|
|
/**
|
|
|
|
* PreferencesGetLayout hook handler.
|
|
|
|
*
|
|
|
|
* Use mobile layout in Special:Preferences
|
2022-10-20 17:04:26 +00:00
|
|
|
* @see https://www.mediawiki.org/wiki/Manual:Hooks/PreferencesGetLayout
|
2022-10-12 13:37:28 +00:00
|
|
|
*
|
|
|
|
* @param bool &$useMobileLayout
|
2024-03-03 14:40:39 +00:00
|
|
|
* @param string $skinName
|
|
|
|
* @param array $skinProperties
|
2022-10-12 13:37:28 +00:00
|
|
|
*/
|
2024-03-03 14:40:39 +00:00
|
|
|
public function onPreferencesGetLayout( &$useMobileLayout, $skinName, $skinProperties = [] ) {
|
|
|
|
if ( $skinName === 'minerva' ) {
|
2022-10-12 13:37:28 +00:00
|
|
|
$useMobileLayout = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-17 21:01:29 +00:00
|
|
|
/**
|
|
|
|
* Disable recent changes enhanced mode (table mode)
|
|
|
|
* @see https://www.mediawiki.org/wiki/Manual:Hooks/FetchChangesList
|
|
|
|
*
|
|
|
|
* @param User $user
|
2022-02-15 18:40:10 +00:00
|
|
|
* @param Skin $skin
|
2022-08-21 17:03:43 +00:00
|
|
|
* @param ChangesList|null &$list
|
|
|
|
* @param ChangesListFilterGroup[] $groups
|
2019-07-31 18:35:49 +00:00
|
|
|
* @return bool|null
|
2019-07-17 21:01:29 +00:00
|
|
|
*/
|
2022-08-21 17:03:43 +00:00
|
|
|
public function onFetchChangesList( $user, $skin, &$list, $groups ) {
|
2019-07-31 18:35:49 +00:00
|
|
|
if ( $skin->getSkinName() === 'minerva' ) {
|
|
|
|
// The new changes list (table-based) does not work with Minerva
|
|
|
|
$list = new OldChangesList( $skin->getContext(), $groups );
|
|
|
|
// returning false makes sure $list is used instead.
|
|
|
|
return false;
|
|
|
|
}
|
2019-07-17 21:01:29 +00:00
|
|
|
}
|
|
|
|
|
2017-07-12 15:12:40 +00:00
|
|
|
/**
|
|
|
|
* Invocation of hook SpecialPageBeforeExecute
|
|
|
|
*
|
|
|
|
* We use this hook to ensure that login/account creation pages
|
|
|
|
* are redirected to HTTPS if they are not accessed via HTTPS and
|
|
|
|
* $wgSecureLogin == true - but only when using the
|
|
|
|
* mobile site.
|
|
|
|
*
|
|
|
|
* @param SpecialPage $special
|
|
|
|
* @param string $subpage
|
|
|
|
*/
|
2022-08-21 17:03:43 +00:00
|
|
|
public function onSpecialPageBeforeExecute( $special, $subpage ) {
|
2017-07-12 15:12:40 +00:00
|
|
|
$name = $special->getName();
|
2023-12-04 20:42:13 +00:00
|
|
|
if ( !in_array( $name, [ 'Recentchanges', 'Userlogin', 'CreateAccount' ] ) ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$skin = $special->getSkin();
|
|
|
|
if ( !$skin instanceof SkinMinerva ) {
|
|
|
|
return;
|
|
|
|
}
|
2017-07-12 15:12:40 +00:00
|
|
|
$request = $special->getRequest();
|
2023-12-04 20:42:13 +00:00
|
|
|
if ( $name === 'Recentchanges' ) {
|
2024-02-26 19:47:57 +00:00
|
|
|
$isEnhancedDefaultForUser = $this->userOptionsLookup
|
2023-12-04 20:42:13 +00:00
|
|
|
->getBoolOption( $special->getUser(), 'usenewrc' );
|
|
|
|
$enhanced = $request->getBool( 'enhanced', $isEnhancedDefaultForUser );
|
|
|
|
if ( $enhanced ) {
|
|
|
|
$special->getOutput()->addHTML( Html::warningBox(
|
|
|
|
$special->msg( 'skin-minerva-recentchanges-warning-enhanced-not-supported' )->parse()
|
|
|
|
) );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Add default warning message to Special:UserLogin and Special:UserCreate
|
|
|
|
// if no warning message set.
|
|
|
|
if (
|
2024-03-28 21:00:03 +00:00
|
|
|
!$request->getCheck( 'warning' ) &&
|
2023-12-04 20:42:13 +00:00
|
|
|
!$special->getUser()->isRegistered() &&
|
|
|
|
!$request->wasPosted()
|
|
|
|
) {
|
|
|
|
$request->setVal( 'warning', 'mobile-frontend-generic-login-new' );
|
2017-07-12 15:12:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-01 20:15:19 +00:00
|
|
|
/**
|
|
|
|
* UserLogoutComplete hook handler.
|
|
|
|
* Resets skin options if a user logout occurs - this is necessary as the
|
|
|
|
* RequestContextCreateSkinMobile hook runs before the UserLogout hook.
|
|
|
|
*
|
|
|
|
* @param User $user
|
2022-08-21 17:03:43 +00:00
|
|
|
* @param string &$inject_html
|
|
|
|
* @param string $oldName
|
2019-08-01 20:15:19 +00:00
|
|
|
*/
|
2022-08-21 17:03:43 +00:00
|
|
|
public function onUserLogoutComplete( $user, &$inject_html, $oldName ) {
|
2024-03-12 19:10:35 +00:00
|
|
|
if ( $this->mobileContext ) {
|
2024-03-12 19:35:14 +00:00
|
|
|
$this->skinOptions->setMinervaSkinOptions( $this->mobileContext, $this->mobileContext->getSkin() );
|
2019-08-01 20:15:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-13 14:29:05 +00:00
|
|
|
/**
|
|
|
|
* ResourceLoaderGetConfigVars hook handler.
|
|
|
|
* Used for setting JS variables which are pulled in dynamically with RL
|
|
|
|
* instead of embedded directly on the page with a script tag.
|
2020-04-21 22:44:18 +00:00
|
|
|
* These vars have a shorter cache-life than those in `getJsConfigVars`.
|
2018-08-13 14:29:05 +00:00
|
|
|
*
|
|
|
|
* @param array &$vars Array of variables to be added into the output of the RL startup module.
|
2018-10-31 21:32:45 +00:00
|
|
|
* @param string $skin
|
2022-08-21 17:03:43 +00:00
|
|
|
* @param Config $config
|
2018-08-13 14:29:05 +00:00
|
|
|
*/
|
2022-08-21 17:03:43 +00:00
|
|
|
public function onResourceLoaderGetConfigVars( array &$vars, $skin, Config $config ): void {
|
2018-10-31 21:32:45 +00:00
|
|
|
if ( $skin === 'minerva' ) {
|
2019-09-20 21:03:59 +00:00
|
|
|
// This is to let the UI adjust itself to a wiki that is always read-only.
|
|
|
|
// Ignore temporary read-only on live wikis, requires heavy DB check (T233458).
|
2024-02-26 19:47:57 +00:00
|
|
|
$roConf = $this->configuredReadOnlyMode;
|
2018-10-31 21:32:45 +00:00
|
|
|
$vars += [
|
|
|
|
'wgMinervaABSamplingRate' => $config->get( 'MinervaABSamplingRate' ),
|
2019-09-20 21:03:59 +00:00
|
|
|
'wgMinervaReadOnly' => $roConf->isReadOnly(),
|
2018-10-31 21:32:45 +00:00
|
|
|
];
|
|
|
|
}
|
2018-08-13 14:29:05 +00:00
|
|
|
}
|
2020-06-18 19:11:32 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Modifies the `<body>` element's attributes.
|
|
|
|
*
|
|
|
|
* By default, the `class` attribute is set to the output's "bodyClassName"
|
|
|
|
* property.
|
|
|
|
*
|
|
|
|
* @param OutputPage $out
|
|
|
|
* @param Skin $skin
|
|
|
|
* @param string[] &$bodyAttrs
|
|
|
|
*/
|
2022-08-21 17:03:43 +00:00
|
|
|
public function onOutputPageBodyAttributes( $out, $skin, &$bodyAttrs ): void {
|
2020-06-18 19:11:32 +00:00
|
|
|
$classes = $out->getProperty( 'bodyClassName' );
|
2020-08-01 18:12:31 +00:00
|
|
|
$isMinerva = $skin instanceof SkinMinerva;
|
2020-06-18 19:11:32 +00:00
|
|
|
|
2024-03-12 19:35:14 +00:00
|
|
|
if ( $isMinerva && $this->skinOptions->get( SkinOptions::HISTORY_IN_PAGE_ACTIONS ) ) {
|
2020-06-18 19:11:32 +00:00
|
|
|
// Class is used when page actions is modified to contain more elements
|
|
|
|
$classes .= ' minerva--history-page-action-enabled';
|
|
|
|
}
|
|
|
|
|
2020-08-01 18:12:31 +00:00
|
|
|
if ( $isMinerva ) {
|
|
|
|
$bodyAttrs['class'] .= ' ' . $classes;
|
2020-06-18 19:11:32 +00:00
|
|
|
}
|
|
|
|
}
|
2020-07-14 12:59:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* SkinPageReadyConfig hook handler
|
|
|
|
*
|
2022-08-21 17:03:43 +00:00
|
|
|
* @param Context $context
|
2020-07-14 12:59:40 +00:00
|
|
|
* @param mixed[] &$config Associative array of configurable options
|
|
|
|
*/
|
2022-08-21 17:03:43 +00:00
|
|
|
public function onSkinPageReadyConfig(
|
|
|
|
Context $context,
|
2020-07-14 12:59:40 +00:00
|
|
|
array &$config
|
2022-08-21 17:03:43 +00:00
|
|
|
): void {
|
2020-07-14 12:59:40 +00:00
|
|
|
if ( $context->getSkin() === 'minerva' ) {
|
|
|
|
$config['search'] = false;
|
2022-11-22 19:29:22 +00:00
|
|
|
// Enable collapsible styles on Minerva. Projects are already doing this via gadgets
|
|
|
|
// which creates an unpredictable testing environment so it is better to match production.
|
|
|
|
// NOTE: This is enabled despite the well documented problems with the current design on T111565.
|
|
|
|
$config['collapsible'] = true;
|
2021-02-10 23:35:17 +00:00
|
|
|
$config['selectorLogoutLink'] = 'a.menu__item--logout[data-mw="interface"]';
|
2020-07-14 12:59:40 +00:00
|
|
|
}
|
|
|
|
}
|
2023-09-29 21:55:29 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Force inline diffs on mobile site.
|
|
|
|
*
|
|
|
|
* @param DifferenceEngine $differenceEngine
|
|
|
|
*/
|
|
|
|
public function onDifferenceEngineViewHeader( $differenceEngine ) {
|
|
|
|
$skin = $differenceEngine->getSkin();
|
|
|
|
if ( $skin->getSkinName() !== 'minerva' ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$differenceEngine->setSlotDiffOptions( [
|
|
|
|
'diff-type' => 'inline',
|
|
|
|
] );
|
|
|
|
}
|
2017-07-12 15:12:40 +00:00
|
|
|
}
|