resourceloader: Move site-level mw.config from startup to mediawiki.base

This data isn't needed for startup, and we can shave off a few K from
startup by moving it to mediawiki.base instead.

It was requested that this be done as a "package file", which
necessitated some other minor structural changes to mediawiki.base as
well.

Bug: T235350
Change-Id: I525a5203533089d5a542f83a847be58a10cb6319
This commit is contained in:
Brad Jorsch 2020-02-06 15:24:56 -05:00 committed by Krinkle
parent 43d4d098c6
commit 036cde7a04
6 changed files with 116 additions and 110 deletions

View file

@ -1817,4 +1817,95 @@ MESSAGE;
return $parser;
}
/**
* Get site configuration settings (for mw.config)
* @internal Exposed for use from Resources.php
* @param ResourceLoaderContext $context
* @param Config $conf
* @return array
*/
public static function getSiteConfigSettings(
ResourceLoaderContext $context, Config $conf
) : array {
/**
* Namespace related preparation
* - wgNamespaceIds: Key-value pairs of all localized, canonical and aliases for namespaces.
* - wgCaseSensitiveNamespaces: Array of namespaces that are case-sensitive.
*/
$contLang = MediaWikiServices::getInstance()->getContentLanguage();
$namespaceIds = $contLang->getNamespaceIds();
$caseSensitiveNamespaces = [];
$nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
foreach ( $nsInfo->getCanonicalNamespaces() as $index => $name ) {
$namespaceIds[$contLang->lc( $name )] = $index;
if ( !$nsInfo->isCapitalized( $index ) ) {
$caseSensitiveNamespaces[] = $index;
}
}
$illegalFileChars = $conf->get( 'IllegalFileChars' );
// Build list of variables
$skin = $context->getSkin();
// Start of supported and stable config vars (for use by extensions/gadgets).
$vars = [
'debug' => $context->getDebug(),
'skin' => $skin,
'stylepath' => $conf->get( 'StylePath' ),
'wgArticlePath' => $conf->get( 'ArticlePath' ),
'wgScriptPath' => $conf->get( 'ScriptPath' ),
'wgScript' => $conf->get( 'Script' ),
'wgSearchType' => $conf->get( 'SearchType' ),
'wgVariantArticlePath' => $conf->get( 'VariantArticlePath' ),
'wgServer' => $conf->get( 'Server' ),
'wgServerName' => $conf->get( 'ServerName' ),
'wgUserLanguage' => $context->getLanguage(),
'wgContentLanguage' => $contLang->getCode(),
'wgVersion' => $conf->get( 'Version' ),
'wgEnableAPI' => true, // Deprecated since MW 1.32
'wgEnableWriteAPI' => true, // Deprecated since MW 1.32
'wgFormattedNamespaces' => $contLang->getFormattedNamespaces(),
'wgNamespaceIds' => $namespaceIds,
'wgContentNamespaces' => $nsInfo->getContentNamespaces(),
'wgSiteName' => $conf->get( 'Sitename' ),
'wgDBname' => $conf->get( 'DBname' ),
'wgWikiID' => WikiMap::getWikiIdFromDbDomain( WikiMap::getCurrentWikiDbDomain() ),
'wgCaseSensitiveNamespaces' => $caseSensitiveNamespaces,
'wgCommentByteLimit' => null,
'wgCommentCodePointLimit' => CommentStore::COMMENT_CHARACTER_LIMIT,
'wgExtensionAssetsPath' => $conf->get( 'ExtensionAssetsPath' ),
];
// End of stable config vars.
// Internal variables for use by MediaWiki core and/or ResourceLoader.
$vars += [
// @internal For mediawiki.widgets
'wgUrlProtocols' => wfUrlProtocols(),
// @internal For mediawiki.page.watch
// Force object to avoid "empty" associative array from
// becoming [] instead of {} in JS (T36604)
'wgActionPaths' => (object)$conf->get( 'ActionPaths' ),
// @internal For mediawiki.language
'wgTranslateNumerals' => $conf->get( 'TranslateNumerals' ),
// @internal For mediawiki.Title
'wgExtraSignatureNamespaces' => $conf->get( 'ExtraSignatureNamespaces' ),
// @internal For mediawiki.cookie
'wgCookiePrefix' => $conf->get( 'CookiePrefix' ),
'wgCookieDomain' => $conf->get( 'CookieDomain' ),
'wgCookiePath' => $conf->get( 'CookiePath' ),
'wgCookieExpiration' => $conf->get( 'CookieExpiration' ),
// @internal For mediawiki.Title
'wgLegalTitleChars' => Title::convertByteClassToUnicodeClass( Title::legalChars() ),
'wgIllegalFileChars' => Title::convertByteClassToUnicodeClass( $illegalFileChars ),
// @internal For mediawiki.ForeignUpload
'wgForeignUploadTargets' => $conf->get( 'ForeignUploadTargets' ),
'wgEnableUploads' => $conf->get( 'EnableUploads' ),
];
Hooks::run( 'ResourceLoaderGetConfigVars', [ &$vars, $skin, $conf ] );
return $vars;
}
}

View file

@ -20,8 +20,6 @@
* @author Roan Kattouw
*/
use MediaWiki\MediaWikiServices;
/**
* Module for ResourceLoader initialization.
*
@ -54,95 +52,6 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
'private' => 1,
];
/**
* @internal Exposed for WMF maintenance script
* @param ResourceLoaderContext $context
* @return array
*/
public function getConfigSettings( ResourceLoaderContext $context ) : array {
$conf = $this->getConfig();
/**
* Namespace related preparation
* - wgNamespaceIds: Key-value pairs of all localized, canonical and aliases for namespaces.
* - wgCaseSensitiveNamespaces: Array of namespaces that are case-sensitive.
*/
$contLang = MediaWikiServices::getInstance()->getContentLanguage();
$namespaceIds = $contLang->getNamespaceIds();
$caseSensitiveNamespaces = [];
$nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
foreach ( $nsInfo->getCanonicalNamespaces() as $index => $name ) {
$namespaceIds[$contLang->lc( $name )] = $index;
if ( !$nsInfo->isCapitalized( $index ) ) {
$caseSensitiveNamespaces[] = $index;
}
}
$illegalFileChars = $conf->get( 'IllegalFileChars' );
// Build list of variables
$skin = $context->getSkin();
// Start of supported and stable config vars (for use by extensions/gadgets).
$vars = [
'debug' => $context->getDebug(),
'skin' => $skin,
'stylepath' => $conf->get( 'StylePath' ),
'wgArticlePath' => $conf->get( 'ArticlePath' ),
'wgScriptPath' => $conf->get( 'ScriptPath' ),
'wgScript' => $conf->get( 'Script' ),
'wgSearchType' => $conf->get( 'SearchType' ),
'wgVariantArticlePath' => $conf->get( 'VariantArticlePath' ),
'wgServer' => $conf->get( 'Server' ),
'wgServerName' => $conf->get( 'ServerName' ),
'wgUserLanguage' => $context->getLanguage(),
'wgContentLanguage' => $contLang->getCode(),
'wgVersion' => $conf->get( 'Version' ),
'wgEnableAPI' => true, // Deprecated since MW 1.32
'wgEnableWriteAPI' => true, // Deprecated since MW 1.32
'wgFormattedNamespaces' => $contLang->getFormattedNamespaces(),
'wgNamespaceIds' => $namespaceIds,
'wgContentNamespaces' => $nsInfo->getContentNamespaces(),
'wgSiteName' => $conf->get( 'Sitename' ),
'wgDBname' => $conf->get( 'DBname' ),
'wgWikiID' => WikiMap::getWikiIdFromDbDomain( WikiMap::getCurrentWikiDbDomain() ),
'wgCaseSensitiveNamespaces' => $caseSensitiveNamespaces,
'wgCommentByteLimit' => null,
'wgCommentCodePointLimit' => CommentStore::COMMENT_CHARACTER_LIMIT,
'wgExtensionAssetsPath' => $conf->get( 'ExtensionAssetsPath' ),
];
// End of stable config vars.
// Internal variables for use by MediaWiki core and/or ResourceLoader.
$vars += [
// @internal For mediawiki.widgets
'wgUrlProtocols' => wfUrlProtocols(),
// @internal For mediawiki.page.watch
// Force object to avoid "empty" associative array from
// becoming [] instead of {} in JS (T36604)
'wgActionPaths' => (object)$conf->get( 'ActionPaths' ),
// @internal For mediawiki.language
'wgTranslateNumerals' => $conf->get( 'TranslateNumerals' ),
// @internal For mediawiki.Title
'wgExtraSignatureNamespaces' => $conf->get( 'ExtraSignatureNamespaces' ),
// @internal For mediawiki.cookie
'wgCookiePrefix' => $conf->get( 'CookiePrefix' ),
'wgCookieDomain' => $conf->get( 'CookieDomain' ),
'wgCookiePath' => $conf->get( 'CookiePath' ),
'wgCookieExpiration' => $conf->get( 'CookieExpiration' ),
// @internal For mediawiki.Title
'wgLegalTitleChars' => Title::convertByteClassToUnicodeClass( Title::legalChars() ),
'wgIllegalFileChars' => Title::convertByteClassToUnicodeClass( $illegalFileChars ),
// @internal For mediawiki.ForeignUpload
'wgForeignUploadTargets' => $conf->get( 'ForeignUploadTargets' ),
'wgEnableUploads' => $conf->get( 'EnableUploads' ),
];
Hooks::run( 'ResourceLoaderGetConfigVars', [ &$vars, $skin, $conf ] );
return $vars;
}
/**
* Recursively get all explicit and implicit dependencies for to the given module.
*
@ -477,9 +386,6 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
// Perform string replacements for startup.js
$pairs = [
'$VARS.configuration' => $context->encodeJson(
$this->getConfigSettings( $context )
),
// Raw JavaScript code (not JSON)
'$CODE.registrations();' => trim( $this->getModuleRegistrations( $context ) ),
'$CODE.defineLoader();' => $mwLoaderCode,

View file

@ -107,16 +107,19 @@ return [
'targets' => [ 'desktop', 'mobile' ],
],
'mediawiki.base' => [
'scripts' => array_merge(
[
// This MUST be kept in sync with maintenance/jsduck/eg-iframe.html
'resources/src/mediawiki.base/mediawiki.errorLogger.js',
'resources/src/mediawiki.base/mediawiki.base.js',
],
$GLOBALS['wgIncludeLegacyJavaScript']
? [ 'resources/src/mediawiki.base/legacy.wikibits.js' ]
: []
),
'localBasePath' => "$IP/resources/src/mediawiki.base",
'packageFiles' => [
// This MUST be kept in sync with maintenance/jsduck/eg-iframe.html
'mediawiki.base.js',
'mediawiki.errorLogger.js',
// (not this though)
[ 'name' => 'config.json', 'callback' => 'ResourceLoader::getSiteConfigSettings' ],
[ 'name' => 'legacy.wikibits.js', 'callback' => function () {
global $wgIncludeLegacyJavaScript;
return $wgIncludeLegacyJavaScript ? new ResourceLoaderFilePath( 'legacy.wikibits.js' ) : '';
} ],
],
'dependencies' => 'jquery',
'targets' => [ 'desktop', 'mobile' ],
],

View file

@ -23,6 +23,13 @@
trackHandlers = [],
queue;
// Apply site-level config
mw.config.set( require( './config.json' ) );
// Load other files in the package
require( './mediawiki.errorLogger.js' );
require( './legacy.wikibits.js' );
/**
* Object constructor for messages.
*

View file

@ -4,7 +4,7 @@
* - Beware: This file MUST parse without errors on even the most ancient of browsers!
*/
/* eslint-disable no-implicit-globals */
/* global $VARS, $CODE, RLQ:true, NORLQ:true */
/* global $CODE, RLQ:true, NORLQ:true */
/**
* See <https://www.mediawiki.org/wiki/Compatibility#Browsers>
@ -109,7 +109,7 @@ if ( !isCompatible( navigator.userAgent ) ) {
$CODE.defineLoader();
/**
* The $CODE and $VARS placeholders are substituted in ResourceLoaderStartUpModule.php.
* The $CODE placeholder is substituted in ResourceLoaderStartUpModule.php.
*/
( function () {
/* global mw */
@ -117,9 +117,8 @@ if ( !isCompatible( navigator.userAgent ) ) {
$CODE.registrations();
mw.config.set( $VARS.configuration );
// For the current page
mw.config.set( window.RLCONF || {} );
mw.config.set( window.RLCONF || {} ); // mw.loader needs wgCSPNonce and wgUserName
mw.loader.state( window.RLSTATE || {} );
mw.loader.load( window.RLPAGEMODULES || [] );

View file

@ -799,10 +799,10 @@ mw.loader.register([
'Deterministic version hash'
);
$this->assertNotEquals(
$this->assertEquals(
$version1,
$version3,
'Config change impacts version hash'
'Config change no longer impacts version hash'
);
}