Split Data class into ResourceLoaderData and LanguageData

The Data class contained utilities for two unrelated purposes.
Split each half to a separate class.

Notably, this improves the signature of the getLocalData() function.

Change-Id: Icde615fb9d483fee1f352c34909b37f8ffde8081
This commit is contained in:
Bartosz Dziewoński 2022-02-19 05:03:09 +01:00
parent ae9f26a9e5
commit 99b5de8038
8 changed files with 167 additions and 139 deletions

View file

@ -41,7 +41,7 @@
"controller.js",
{
"name": "controller/contLangMessages.json",
"callback": "\\MediaWiki\\Extension\\DiscussionTools\\Data::getContentLanguageMessages",
"callback": "\\MediaWiki\\Extension\\DiscussionTools\\ResourceLoaderData::getContentLanguageMessages",
"callbackParam": [
"discussiontools-defaultsummary-reply",
"newsectionsummary",
@ -74,7 +74,7 @@
"lib/moment-timezone/moment-timezone-with-data-1970-2030.js",
{
"name": "parser/data.json",
"callback": "\\MediaWiki\\Extension\\DiscussionTools\\Data::getLocalData"
"callback": "\\MediaWiki\\Extension\\DiscussionTools\\ResourceLoaderData::getLocalData"
}
],
"styles": [
@ -157,8 +157,8 @@
"AbandonTopicDialog.js",
{
"name": "licenseMessages.json",
"callback": "\\MediaWiki\\Extension\\DiscussionTools\\Data::getTermsOfUseMessagesParsed",
"versionCallback": "\\MediaWiki\\Extension\\DiscussionTools\\Data::getTermsOfUseMessagesVersion"
"callback": "\\MediaWiki\\Extension\\DiscussionTools\\ResourceLoaderData::getTermsOfUseMessagesParsed",
"versionCallback": "\\MediaWiki\\Extension\\DiscussionTools\\ResourceLoaderData::getTermsOfUseMessagesVersion"
}
],
"styles": [
@ -202,7 +202,7 @@
"optionalDependencies": {
"ConfirmEdit": "ext.confirmEdit.CaptchaInputWidget"
},
"factory": "\\MediaWiki\\Extension\\DiscussionTools\\Data::addOptionalDependencies",
"factory": "\\MediaWiki\\Extension\\DiscussionTools\\ResourceLoaderData::addOptionalDependencies",
"targets": [
"desktop",
"mobile"
@ -266,7 +266,7 @@
"qunit/testUtils.js",
{
"name": "data-en.json",
"callback": "\\MediaWiki\\Extension\\DiscussionTools\\Data::getLocalData",
"callback": "\\MediaWiki\\Extension\\DiscussionTools\\ResourceLoaderData::getLocalData",
"callbackParam": "en"
},
"data/arwiki-config.json",

View file

@ -69,7 +69,7 @@ class CommentParser {
if ( !$data ) {
// TODO: Instead of passing data used for mocking, mock the methods that fetch the data.
$data = Data::getLocalData( null, $config, $language );
$data = LanguageData::getLocalData( $config, $language );
}
$this->dateFormat = $data['dateFormat'];

View file

@ -1,6 +1,6 @@
<?php
/**
* DiscussionTools data generators
* Generates language-specific data used by DiscussionTools.
*
* @file
* @ingroup Extensions
@ -11,37 +11,19 @@ namespace MediaWiki\Extension\DiscussionTools;
use Config;
use DateTimeZone;
use ExtensionRegistry;
use ILanguageConverter;
use Language;
use MediaWiki\MediaWikiServices;
use MessageLocalizer;
use ResourceLoaderContext;
use ResourceLoaderFileModule;
use ResourceLoaderModule;
use Title;
class Data {
class LanguageData {
/**
* Part of the 'ext.discussionTools.init' module.
* Compute data we need to parse discussion threads on pages.
*
* We need all of this data *in content language*. Some of it is already available in JS, but only
* in client language, so it's useless for us (e.g. digit transform table, month name messages).
*
* @param ResourceLoaderContext|null $context
* @param Config $config
* @param string|Language|null $lang
* @param Language $lang
* @return array
*/
public static function getLocalData(
?ResourceLoaderContext $context, Config $config, $lang = null
): array {
if ( !$lang ) {
$lang = MediaWikiServices::getInstance()->getContentLanguage();
} elseif ( !( $lang instanceof Language ) ) {
$lang = MediaWikiServices::getInstance()->getLanguageFactory()->getLanguage( $lang );
}
public static function getLocalData( Config $config, Language $lang ): array {
$langConv = MediaWikiServices::getInstance()->getLanguageConverterFactory()
->getLanguageConverter( $lang );
@ -219,106 +201,4 @@ class Data {
return $s;
}
/**
* Return messages in content language, for use in a ResourceLoader module.
*
* @param ResourceLoaderContext $context
* @param Config $config
* @param array $messagesKeys
* @return array
*/
public static function getContentLanguageMessages(
ResourceLoaderContext $context, Config $config, array $messagesKeys = []
): array {
return array_combine(
$messagesKeys,
array_map( static function ( $key ) {
return wfMessage( $key )->inContentLanguage()->text();
}, $messagesKeys )
);
}
/**
* Return information about terms-of-use messages.
*
* @param MessageLocalizer $context
* @param Config $config
* @return array Map from internal name to array of parameters for MessageLocalizer::msg()
*/
private static function getTermsOfUseMessages(
MessageLocalizer $context, Config $config
): array {
$messages = [
'reply' => [ 'discussiontools-replywidget-terms-click',
$context->msg( 'discussiontools-replywidget-reply' )->text() ],
'newtopic' => [ 'discussiontools-replywidget-terms-click',
$context->msg( 'discussiontools-replywidget-newtopic' )->text() ],
];
$hookContainer = MediaWikiServices::getInstance()->getHookContainer();
$hookContainer->run( 'DiscussionToolsTermsOfUseMessages', [ &$messages, $context, $config ] );
return $messages;
}
/**
* Return parsed terms-of-use messages, for use in a ResourceLoader module.
*
* @param MessageLocalizer $context
* @param Config $config
* @return array
*/
public static function getTermsOfUseMessagesParsed(
MessageLocalizer $context, Config $config
): array {
$messages = self::getTermsOfUseMessages( $context, $config );
foreach ( $messages as &$msg ) {
$msg = $context->msg( ...$msg )->parse();
}
return $messages;
}
/**
* Return information about terms-of-use messages, for use in a ResourceLoader module as
* 'versionCallback'. This is to avoid calling the parser from version invalidation code.
*
* @param MessageLocalizer $context
* @param Config $config
* @return array
*/
public static function getTermsOfUseMessagesVersion(
MessageLocalizer $context, Config $config
): array {
$messages = self::getTermsOfUseMessages( $context, $config );
foreach ( $messages as &$msg ) {
$message = $context->msg( ...$msg );
$msg = [
// Include the text of the message, in case the canonical translation changes
$message->plain(),
// Include the page touched time, in case the on-wiki override is invalidated
Title::makeTitle( NS_MEDIAWIKI, ucfirst( $message->getKey() ) )->getTouched(),
];
}
return $messages;
}
/**
* Add optional dependencies to a ResourceLoader module definition depending on loaded extensions.
*
* @param array $info
* @return ResourceLoaderModule
*/
public static function addOptionalDependencies( array $info ): ResourceLoaderModule {
$extensionRegistry = ExtensionRegistry::getInstance();
foreach ( $info['optionalDependencies'] as $ext => $deps ) {
if ( $extensionRegistry->isLoaded( $ext ) ) {
$info['dependencies'] = array_merge( $info['dependencies'], (array)$deps );
}
}
$class = $info['class'] ?? ResourceLoaderFileModule::class;
return new $class( $info );
}
}

View file

@ -0,0 +1,146 @@
<?php
/**
* Utilities for ResourceLoader modules used by DiscussionTools.
*
* @file
* @ingroup Extensions
* @license MIT
*/
namespace MediaWiki\Extension\DiscussionTools;
use Config;
use ExtensionRegistry;
use MediaWiki\MediaWikiServices;
use MessageLocalizer;
use ResourceLoaderContext;
use ResourceLoaderFileModule;
use ResourceLoaderModule;
use Title;
class ResourceLoaderData {
/**
* Used for the 'ext.discussionTools.init' module and the test module.
*
* We need all of this data *in content language*. Some of it is already available in JS, but only
* in client language, so it's useless for us (e.g. digit transform table, month name messages).
*
* @param ResourceLoaderContext $context
* @param Config $config
* @param string|null $langCode
* @return array
*/
public static function getLocalData(
ResourceLoaderContext $context, Config $config, ?string $langCode = null
): array {
if ( $langCode === null ) {
$lang = MediaWikiServices::getInstance()->getContentLanguage();
} else {
$lang = MediaWikiServices::getInstance()->getLanguageFactory()->getLanguage( $langCode );
}
return LanguageData::getLocalData( $config, $lang );
}
/**
* Return messages in content language, for use in a ResourceLoader module.
*
* @param ResourceLoaderContext $context
* @param Config $config
* @param array $messagesKeys
* @return array
*/
public static function getContentLanguageMessages(
ResourceLoaderContext $context, Config $config, array $messagesKeys = []
): array {
return array_combine(
$messagesKeys,
array_map( static function ( $key ) {
return wfMessage( $key )->inContentLanguage()->text();
}, $messagesKeys )
);
}
/**
* Return information about terms-of-use messages.
*
* @param MessageLocalizer $context
* @param Config $config
* @return array Map from internal name to array of parameters for MessageLocalizer::msg()
*/
private static function getTermsOfUseMessages(
MessageLocalizer $context, Config $config
): array {
$messages = [
'reply' => [ 'discussiontools-replywidget-terms-click',
$context->msg( 'discussiontools-replywidget-reply' )->text() ],
'newtopic' => [ 'discussiontools-replywidget-terms-click',
$context->msg( 'discussiontools-replywidget-newtopic' )->text() ],
];
$hookContainer = MediaWikiServices::getInstance()->getHookContainer();
$hookContainer->run( 'DiscussionToolsTermsOfUseMessages', [ &$messages, $context, $config ] );
return $messages;
}
/**
* Return parsed terms-of-use messages, for use in a ResourceLoader module.
*
* @param MessageLocalizer $context
* @param Config $config
* @return array
*/
public static function getTermsOfUseMessagesParsed(
MessageLocalizer $context, Config $config
): array {
$messages = self::getTermsOfUseMessages( $context, $config );
foreach ( $messages as &$msg ) {
$msg = $context->msg( ...$msg )->parse();
}
return $messages;
}
/**
* Return information about terms-of-use messages, for use in a ResourceLoader module as
* 'versionCallback'. This is to avoid calling the parser from version invalidation code.
*
* @param MessageLocalizer $context
* @param Config $config
* @return array
*/
public static function getTermsOfUseMessagesVersion(
MessageLocalizer $context, Config $config
): array {
$messages = self::getTermsOfUseMessages( $context, $config );
foreach ( $messages as &$msg ) {
$message = $context->msg( ...$msg );
$msg = [
// Include the text of the message, in case the canonical translation changes
$message->plain(),
// Include the page touched time, in case the on-wiki override is invalidated
Title::makeTitle( NS_MEDIAWIKI, ucfirst( $message->getKey() ) )->getTouched(),
];
}
return $messages;
}
/**
* Add optional dependencies to a ResourceLoader module definition depending on loaded extensions.
*
* @param array $info
* @return ResourceLoaderModule
*/
public static function addOptionalDependencies( array $info ): ResourceLoaderModule {
$extensionRegistry = ExtensionRegistry::getInstance();
foreach ( $info['optionalDependencies'] as $ext => $deps ) {
if ( $extensionRegistry->isLoaded( $ext ) ) {
$info['dependencies'] = array_merge( $info['dependencies'], (array)$deps );
}
}
$class = $info['class'] ?? ResourceLoaderFileModule::class;
return new $class( $info );
}
}

View file

@ -8,7 +8,7 @@ var
CommentItem = require( './CommentItem.js' ),
HeadingItem = require( './HeadingItem.js' ),
ThreadItem = require( './ThreadItem.js' ),
// Data::getLocalData()
// LanguageData::getLocalData()
data = require( './parser/data.json' ),
moment = require( './lib/moment-timezone/moment-timezone-with-data-1970-2030.js' );

View file

@ -1,5 +1,5 @@
var
// Data::getLocalData()
// LanguageData::getLocalData()
parserData = require( './parser/data.json' ),
utils = require( './utils.js' );
var featuresEnabled = mw.config.get( 'wgDiscussionToolsFeaturesEnabled' ) || {};

View file

@ -1,4 +1,4 @@
Minimal overrides for Data::getLocalData() and mw.config
Minimal overrides for LanguageData::getLocalData() and mw.config
required for us to be able to parse HTML generated by the given wiki.
To make one of these files, run the following in browser console:

View file

@ -3,12 +3,13 @@
namespace MediaWiki\Extension\DiscussionTools\Tests;
use HashConfig;
use MediaWiki\Extension\DiscussionTools\Data;
use MediaWiki\Extension\DiscussionTools\LanguageData;
use MediaWiki\MediaWikiServices;
/**
* @coversDefaultClass \MediaWiki\Extension\DiscussionTools\Data
* @coversDefaultClass \MediaWiki\Extension\DiscussionTools\LanguageData
*/
class DataTest extends IntegrationTestCase {
class LanguageDataTest extends IntegrationTestCase {
/**
* @dataProvider provideLocalData
@ -22,7 +23,8 @@ class DataTest extends IntegrationTestCase {
] );
$expectedData = self::getJson( $expectedPath );
$data = Data::getLocalData( null, $conf, $langCode );
$lang = MediaWikiServices::getInstance()->getLanguageFactory()->getLanguage( $langCode );
$data = LanguageData::getLocalData( $conf, $lang );
// Optionally write updated content to the JSON files
if ( getenv( 'DISCUSSIONTOOLS_OVERWRITE_TESTS' ) ) {