Merge "resourceloader: Restore mw.loader.store update postponing logic"
[lhc/web/wiklou.git] / includes / resourceloader / ResourceLoaderStartUpModule.php
index a4fd712..99ffcd2 100644 (file)
@@ -20,6 +20,8 @@
  * @author Roan Kattouw
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Module for ResourceLoader initialization.
  *
@@ -53,7 +55,6 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        return $this->configVars[$hash];
                }
 
-               global $wgContLang;
                $conf = $this->getConfig();
 
                // We can't use Title::newMainPage() if 'mainpage' is in
@@ -71,10 +72,11 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                 * - wgNamespaceIds: Key-value pairs of all localized, canonical and aliases for namespaces.
                 * - wgCaseSensitiveNamespaces: Array of namespaces that are case-sensitive.
                 */
-               $namespaceIds = $wgContLang->getNamespaceIds();
+               $contLang = MediaWikiServices::getInstance()->getContentLanguage();
+               $namespaceIds = $contLang->getNamespaceIds();
                $caseSensitiveNamespaces = [];
                foreach ( MWNamespace::getCanonicalNamespaces() as $index => $name ) {
-                       $namespaceIds[$wgContLang->lc( $name )] = $index;
+                       $namespaceIds[$contLang->lc( $name )] = $index;
                        if ( !MWNamespace::isCapitalized( $index ) ) {
                                $caseSensitiveNamespaces[] = $index;
                        }
@@ -101,13 +103,13 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        'wgServer' => $conf->get( 'Server' ),
                        'wgServerName' => $conf->get( 'ServerName' ),
                        'wgUserLanguage' => $context->getLanguage(),
-                       'wgContentLanguage' => $wgContLang->getCode(),
+                       'wgContentLanguage' => $contLang->getCode(),
                        'wgTranslateNumerals' => $conf->get( 'TranslateNumerals' ),
                        'wgVersion' => $conf->get( 'Version' ),
                        'wgEnableAPI' => true, // Deprecated since MW 1.32
                        'wgEnableWriteAPI' => true, // Deprecated since MW 1.32
                        'wgMainPageTitle' => $mainPage->getPrefixedText(),
-                       'wgFormattedNamespaces' => $wgContLang->getFormattedNamespaces(),
+                       'wgFormattedNamespaces' => $contLang->getFormattedNamespaces(),
                        'wgNamespaceIds' => $namespaceIds,
                        'wgContentNamespaces' => MWNamespace::getContentNamespaces(),
                        'wgSiteName' => $conf->get( 'Sitename' ),
@@ -319,17 +321,6 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                return true;
        }
 
-       /**
-        * @param ResourceLoaderContext $context
-        * @return array
-        */
-       public function getPreloadLinks( ResourceLoaderContext $context ) {
-               $url = $this->getBaseModulesUrl( $context );
-               return [
-                       $url => [ 'as' => 'script' ]
-               ];
-       }
-
        /**
         * Internal modules used by ResourceLoader that cannot be depended on.
         *
@@ -353,10 +344,18 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                return [];
        }
 
+       /**
+        * @private For internal use by SpecialJavaScriptTest
+        * @since 1.32
+        * @return array
+        */
+       public function getBaseModulesInternal() {
+               return $this->getBaseModules();
+       }
+
        /**
         * Base modules implicitly available to all modules.
         *
-        * @since 1.32
         * @return array
         */
        private function getBaseModules() {
@@ -370,25 +369,6 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                return $baseModules;
        }
 
-       /**
-        * Get the load URL of the startup modules.
-        *
-        * This is a helper for getScript().
-        *
-        * @param ResourceLoaderContext $context
-        * @return string
-        */
-       private function getBaseModulesUrl( ResourceLoaderContext $context ) {
-               $rl = $context->getResourceLoader();
-               $derivative = new DerivativeResourceLoaderContext( $context );
-               $derivative->setModules( $this->getBaseModules() );
-               $derivative->setOnly( 'scripts' );
-               // Must setModules() before makeVersionQuery()
-               $derivative->setVersion( $rl->makeVersionQuery( $derivative ) );
-
-               return $rl->createLoaderURL( 'local', $derivative );
-       }
-
        /**
         * @param ResourceLoaderContext $context
         * @return string JavaScript code
@@ -399,35 +379,60 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        return '/* Requires only=script */';
                }
 
-               $out = file_get_contents( "$IP/resources/src/startup/startup.js" );
+               $startupCode = file_get_contents( "$IP/resources/src/startup/startup.js" );
 
-               // Keep in sync with maintenance/jsduck/eg-iframe.html and,
-               // keep in sync with 'fileHashes' in StartUpModule::getDefinitionSummary().
+               // The files read here MUST be kept in sync with maintenance/jsduck/eg-iframe.html,
+               // and MUST be considered by 'fileHashes' in StartUpModule::getDefinitionSummary().
                $mwLoaderCode = file_get_contents( "$IP/resources/src/startup/mediawiki.js" ) .
                        file_get_contents( "$IP/resources/src/startup/mediawiki.requestIdleCallback.js" );
                if ( $context->getDebug() ) {
                        $mwLoaderCode .= file_get_contents( "$IP/resources/src/startup/mediawiki.log.js" );
                }
+               if ( $this->getConfig()->get( 'ResourceLoaderEnableJSProfiler' ) ) {
+                       $mwLoaderCode .= file_get_contents( "$IP/resources/src/startup/profiler.js" );
+               }
 
-               $pairs = array_map( function ( $value ) {
+               $mapToJson = function ( $value ) {
                        $value = FormatJson::encode( $value, ResourceLoader::inDebugMode(), FormatJson::ALL_OK );
                        // Fix indentation
                        $value = str_replace( "\n", "\n\t", $value );
                        return $value;
-               }, [
+               };
+
+               // Perform replacements for mediawiki.js
+               $mwLoaderPairs = [
+                       '$VARS.baseModules' => $mapToJson( $this->getBaseModules() ),
+               ];
+               $profilerStubs = [
+                       '$CODE.profileExecuteStart();' => 'mw.loader.profiler.onExecuteStart( module );',
+                       '$CODE.profileExecuteEnd();' => 'mw.loader.profiler.onExecuteEnd( module );',
+                       '$CODE.profileScriptStart();' => 'mw.loader.profiler.onScriptStart( module );',
+                       '$CODE.profileScriptEnd();' => 'mw.loader.profiler.onScriptEnd( module );',
+               ];
+               if ( $this->getConfig()->get( 'ResourceLoaderEnableJSProfiler' ) ) {
+                       // When profiling is enabled, insert the calls.
+                       $mwLoaderPairs += $profilerStubs;
+               } else {
+                       // When disabled (by default), insert nothing.
+                       $mwLoaderPairs += array_fill_keys( array_keys( $profilerStubs ), '' );
+               }
+               $mwLoaderCode = strtr( $mwLoaderCode, $mwLoaderPairs );
+
+               // Perform replacements for startup.js
+               $pairs = array_map( $mapToJson, [
                        '$VARS.wgLegacyJavaScriptGlobals' => $this->getConfig()->get( 'LegacyJavaScriptGlobals' ),
                        '$VARS.configuration' => $this->getConfigSettings( $context ),
-                       // This url may be preloaded. See getPreloadLinks().
-                       '$VARS.baseModulesUri' => $this->getBaseModulesUrl( $context ),
                ] );
+               // Raw JavaScript code (not for JSON)
                $pairs['$CODE.registrations();'] = str_replace(
                        "\n",
                        "\n\t",
                        trim( $this->getModuleRegistrations( $context ) )
                );
                $pairs['$CODE.defineLoader();'] = $mwLoaderCode;
+               $startupCode = strtr( $startupCode, $pairs );
 
-               return strtr( $out, $pairs );
+               return $startupCode;
        }
 
        /**
@@ -446,13 +451,15 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
        public function getDefinitionSummary( ResourceLoaderContext $context ) {
                global $IP;
                $summary = parent::getDefinitionSummary( $context );
-               $summary[] = [
-                       // Detect changes to variables exposed in mw.config (T30899).
+               $startup = [
+                       // getScript() exposes these variables to mw.config (T30899).
                        'vars' => $this->getConfigSettings( $context ),
-                       // Changes how getScript() creates mw.Map for mw.config
+                       // getScript() uses this to decide how configure mw.Map for mw.config.
                        'wgLegacyJavaScriptGlobals' => $this->getConfig()->get( 'LegacyJavaScriptGlobals' ),
-                       // Detect changes to the module registrations
+                       // Detect changes to the module registrations output by getScript().
                        'moduleHashes' => $this->getAllModuleHashes( $context ),
+                       // Detect changes to base modules listed by getScript().
+                       'baseModules' => $this->getBaseModules(),
 
                        'fileHashes' => [
                                $this->safeFileHash( "$IP/resources/src/startup/startup.js" ),
@@ -460,6 +467,13 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                                $this->safeFileHash( "$IP/resources/src/startup/mediawiki.requestIdleCallback.js" ),
                        ],
                ];
+               if ( $context->getDebug() ) {
+                       $startup['fileHashes'][] = $this->safeFileHash( "$IP/resources/src/startup/mediawiki.log.js" );
+               }
+               if ( $this->getConfig()->get( 'ResourceLoaderEnableJSProfiler' ) ) {
+                       $startup['fileHashes'][] = $this->safeFileHash( "$IP/resources/src/startup/profiling.js" );
+               }
+               $summary[] = $startup;
                return $summary;
        }