resourceloader: Add $context to static functions in ResourceLoader
authorFomafix <fomafix@googlemail.com>
Mon, 9 Sep 2019 15:50:13 +0000 (17:50 +0200)
committerFomafix <fomafix@googlemail.com>
Fri, 27 Sep 2019 16:35:55 +0000 (18:35 +0200)
This change allows to use the context in the functions.

The following internal static functions from ResourceLoader get now a
reference to the ResourceLoaderContext object:
* makeLoaderImplementScript
* makeLoaderStateScript
* makeLoaderRegisterScript
* makeLoaderSourcesScript

ResouceLoader::encodeJsonForScript is duplicated to
ResourceLoaderContext::encodeJson loading the debug mode from context.

ResourceLoader::encodeJsonForScript is kept for other usages without
context.

The debug mode is loaded from $context->getDebug() instead of from
ResourceLoader::inDebugMode(). This does not support to enable the debug
mode by setting the cookie 'resourceLoaderDebug' or the configuration
variable wgResourceLoaderDebug. Only the URL parameter debug=true
enables the debug mode. This should be sufficient for the subsequent
ResourceLoader requests. The tests don't need the global variable
wgResourceLoaderDebug anymore. The initial ResourceLoader context in
OutputPage still uses ResourceLoader::inDebugMode() with cookie and
global configuration variable.

This change adds the parameter $context with a ResourceLoaderContext
object to ResourceLoaderModule::getDeprecationInformation and deprecates
omitting the parameter. Ifa1a3bb56b731b83864022a358916c6aca5d7c10
updates this in extension ExtJSBase.

Bug: T229311
Change-Id: I5341f18625209446a6d006f60244990f65530319

12 files changed:
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderClientHtml.php
includes/resourceloader/ResourceLoaderContext.php
includes/resourceloader/ResourceLoaderFileModule.php
includes/resourceloader/ResourceLoaderLanguageDataModule.php
includes/resourceloader/ResourceLoaderModule.php
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/resourceloader/ResourceLoaderUserDefaultsModule.php
includes/resourceloader/ResourceLoaderUserOptionsModule.php
includes/resourceloader/ResourceLoaderUserTokensModule.php
tests/phpunit/includes/resourceloader/ResourceLoaderStartUpModuleTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderTest.php

index 6121bbf..563b95e 100644 (file)
@@ -813,7 +813,7 @@ class ResourceLoader implements LoggerAwareInterface {
                        $errorResponse = self::makeComment( $errorText );
                        if ( $context->shouldIncludeScripts() ) {
                                $errorResponse .= 'if (window.console && console.error) { console.error('
-                                       . self::encodeJsonForScript( $errorText )
+                                       . $context->encodeJson( $errorText )
                                        . "); }\n";
                        }
 
@@ -1087,7 +1087,14 @@ MESSAGE;
                                                        $strContent = $scripts;
                                                } elseif ( is_array( $scripts ) ) {
                                                        // ...except when $scripts is an array of URLs or an associative array
-                                                       $strContent = self::makeLoaderImplementScript( $implementKey, $scripts, [], [], [] );
+                                                       $strContent = self::makeLoaderImplementScript(
+                                                               $context,
+                                                               $implementKey,
+                                                               $scripts,
+                                                               [],
+                                                               [],
+                                                               []
+                                                       );
                                                }
                                                break;
                                        case 'styles':
@@ -1113,6 +1120,7 @@ MESSAGE;
                                                        }
                                                }
                                                $strContent = self::makeLoaderImplementScript(
+                                                       $context,
                                                        $implementKey,
                                                        $scripts,
                                                        $content['styles'] ?? [],
@@ -1158,7 +1166,7 @@ MESSAGE;
 
                        // Set the state of modules we didn't respond to with mw.loader.implement
                        if ( $states ) {
-                               $stateScript = self::makeLoaderStateScript( $states );
+                               $stateScript = self::makeLoaderStateScript( $context, $states );
                                if ( !$context->getDebug() ) {
                                        $stateScript = self::filter( 'minify-js', $stateScript );
                                }
@@ -1167,7 +1175,7 @@ MESSAGE;
                        }
                } elseif ( $states ) {
                        $this->errors[] = 'Problematic modules: '
-                               . self::encodeJsonForScript( $states );
+                               . $context->encodeJson( $states );
                }
 
                return $out;
@@ -1206,6 +1214,7 @@ MESSAGE;
        /**
         * Return JS code that calls mw.loader.implement with given module properties.
         *
+        * @param ResourceLoaderContext $context
         * @param string $name Module name or implement key (format "`[name]@[version]`")
         * @param XmlJsCode|array|string $scripts Code as XmlJsCode (to be wrapped in a closure),
         *  list of URLs to JavaScript files, string of JavaScript for `$.globalEval`, or array with
@@ -1220,13 +1229,13 @@ MESSAGE;
         * @throws MWException
         * @return string JavaScript code
         */
-       protected static function makeLoaderImplementScript(
-               $name, $scripts, $styles, $messages, $templates
+       private static function makeLoaderImplementScript(
+               ResourceLoaderContext $context, $name, $scripts, $styles, $messages, $templates
        ) {
                if ( $scripts instanceof XmlJsCode ) {
                        if ( $scripts->value === '' ) {
                                $scripts = null;
-                       } elseif ( self::inDebugMode() ) {
+                       } elseif ( $context->getDebug() ) {
                                $scripts = new XmlJsCode( "function ( $, jQuery, require, module ) {\n{$scripts->value}\n}" );
                        } else {
                                $scripts = new XmlJsCode( 'function($,jQuery,require,module){' . $scripts->value . '}' );
@@ -1238,7 +1247,7 @@ MESSAGE;
                                // All of these essentially do $file = $file['content'];, some just have wrapping around it
                                if ( $file['type'] === 'script' ) {
                                        // Multi-file modules only get two parameters ($ and jQuery are being phased out)
-                                       if ( self::inDebugMode() ) {
+                                       if ( $context->getDebug() ) {
                                                $file = new XmlJsCode( "function ( require, module ) {\n{$file['content']}\n}" );
                                        } else {
                                                $file = new XmlJsCode( 'function(require,module){' . $file['content'] . '}' );
@@ -1249,8 +1258,8 @@ MESSAGE;
                        }
                        $scripts = XmlJsCode::encodeObject( [
                                'main' => $scripts['main'],
-                               'files' => XmlJsCode::encodeObject( $files, self::inDebugMode() )
-                       ], self::inDebugMode() );
+                               'files' => XmlJsCode::encodeObject( $files, $context->getDebug() )
+                       ], $context->getDebug() );
                } elseif ( !is_string( $scripts ) && !is_array( $scripts ) ) {
                        throw new MWException( 'Invalid scripts error. Array of URLs or string of code expected.' );
                }
@@ -1267,7 +1276,7 @@ MESSAGE;
                ];
                self::trimArray( $module );
 
-               return Xml::encodeJsCall( 'mw.loader.implement', $module, self::inDebugMode() );
+               return Xml::encodeJsCall( 'mw.loader.implement', $module, $context->getDebug() );
        }
 
        /**
@@ -1349,22 +1358,26 @@ MESSAGE;
         * Returns a JS call to mw.loader.state, which sets the state of one
         * ore more modules to a given value. Has two calling conventions:
         *
-        *    - ResourceLoader::makeLoaderStateScript( $name, $state ):
+        *    - ResourceLoader::makeLoaderStateScript( $context, $name, $state ):
         *         Set the state of a single module called $name to $state
         *
-        *    - ResourceLoader::makeLoaderStateScript( [ $name => $state, ... ] ):
+        *    - ResourceLoader::makeLoaderStateScript( $context, [ $name => $state, ... ] ):
         *         Set the state of modules with the given names to the given states
         *
+        * @internal
+        * @param ResourceLoaderContext $context
         * @param array|string $states
         * @param string|null $state
         * @return string JavaScript code
         */
-       public static function makeLoaderStateScript( $states, $state = null ) {
+       public static function makeLoaderStateScript(
+               ResourceLoaderContext $context, $states, $state = null
+       ) {
                if ( !is_array( $states ) ) {
                        $states = [ $states => $state ];
                }
                return 'mw.loader.state('
-                       . self::encodeJsonForScript( $states )
+                       . $context->encodeJson( $states )
                        . ');';
        }
 
@@ -1409,15 +1422,15 @@ MESSAGE;
         * @par Example
         * @code
         *
-        *     ResourceLoader::makeLoaderRegisterScript( [
+        *     ResourceLoader::makeLoaderRegisterScript( $context, [
         *        [ $name1, $version1, $dependencies1, $group1, $source1, $skip1 ],
         *        [ $name2, $version2, $dependencies1, $group2, $source2, $skip2 ],
         *        ...
         *     ] ):
         * @endcode
         *
-        * @internal
-        * @since 1.32
+        * @internal For use by ResourceLoaderStartUpModule only
+        * @param ResourceLoaderContext $context
         * @param array $modules Array of module registration arrays, each containing
         *  - string: module name
         *  - string: module version
@@ -1427,7 +1440,9 @@ MESSAGE;
         *  - string|null: Script body of a skip function (optional)
         * @return string JavaScript code
         */
-       public static function makeLoaderRegisterScript( array $modules ) {
+       public static function makeLoaderRegisterScript(
+               ResourceLoaderContext $context, array $modules
+       ) {
                // Optimisation: Transform dependency names into indexes when possible
                // to produce smaller output. They are expanded by mw.loader.register on
                // the other end using resolveIndexedDependencies().
@@ -1450,7 +1465,7 @@ MESSAGE;
                array_walk( $modules, [ self::class, 'trimArray' ] );
 
                return 'mw.loader.register('
-                       . self::encodeJsonForScript( $modules )
+                       . $context->encodeJson( $modules )
                        . ');';
        }
 
@@ -1458,22 +1473,28 @@ MESSAGE;
         * Returns JS code which calls mw.loader.addSource() with the given
         * parameters. Has two calling conventions:
         *
-        *   - ResourceLoader::makeLoaderSourcesScript( $id, $properties ):
+        *   - ResourceLoader::makeLoaderSourcesScript( $context, $id, $properties ):
         *       Register a single source
         *
-        *   - ResourceLoader::makeLoaderSourcesScript( [ $id1 => $loadUrl, $id2 => $loadUrl, ... ] );
+        *   - ResourceLoader::makeLoaderSourcesScript( $context,
+        *         [ $id1 => $loadUrl, $id2 => $loadUrl, ... ]
+        *     );
         *       Register sources with the given IDs and properties.
         *
+        * @internal For use by ResourceLoaderStartUpModule only
+        * @param ResourceLoaderContext $context
         * @param string|array $sources Source ID
         * @param string|null $loadUrl load.php url
         * @return string JavaScript code
         */
-       public static function makeLoaderSourcesScript( $sources, $loadUrl = null ) {
+       public static function makeLoaderSourcesScript(
+               ResourceLoaderContext $context, $sources, $loadUrl = null
+       ) {
                if ( !is_array( $sources ) ) {
                        $sources = [ $sources => $loadUrl ];
                }
                return 'mw.loader.addSource('
-                       . self::encodeJsonForScript( $sources )
+                       . $context->encodeJson( $sources )
                        . ');';
        }
 
index ea35de6..b38d722 100644 (file)
@@ -212,7 +212,7 @@ class ResourceLoaderClientHtml {
                                // Load from load.php?only=styles via <link rel=stylesheet>
                                $data['styles'][] = $name;
                        }
-                       $deprecation = $module->getDeprecationInformation();
+                       $deprecation = $module->getDeprecationInformation( $context );
                        if ( $deprecation ) {
                                $data['styleDeprecations'][] = $deprecation;
                        }
@@ -253,14 +253,14 @@ class ResourceLoaderClientHtml {
                // See also startup/startup.js.
                $nojsClass = $nojsClass ?? $this->getDocumentAttributes()['class'];
                $jsClass = preg_replace( '/(^|\s)client-nojs(\s|$)/', '$1client-js$2', $nojsClass );
-               $jsClassJson = ResourceLoader::encodeJsonForScript( $jsClass );
+               $jsClassJson = $this->context->encodeJson( $jsClass );
                $script = <<<JAVASCRIPT
 document.documentElement.className = {$jsClassJson};
 JAVASCRIPT;
 
                // Inline script: Declare mw.config variables for this page.
                if ( $this->config ) {
-                       $confJson = ResourceLoader::encodeJsonForScript( $this->config );
+                       $confJson = $this->context->encodeJson( $this->config );
                        $script .= <<<JAVASCRIPT
 RLCONF = {$confJson};
 JAVASCRIPT;
@@ -269,7 +269,7 @@ JAVASCRIPT;
                // Inline script: Declare initial module states for this page.
                $states = array_merge( $this->exemptStates, $data['states'] );
                if ( $states ) {
-                       $stateJson = ResourceLoader::encodeJsonForScript( $states );
+                       $stateJson = $this->context->encodeJson( $states );
                        $script .= <<<JAVASCRIPT
 RLSTATE = {$stateJson};
 JAVASCRIPT;
@@ -277,7 +277,7 @@ JAVASCRIPT;
 
                // Inline script: Declare general modules to load on this page.
                if ( $data['general'] ) {
-                       $pageModulesJson = ResourceLoader::encodeJsonForScript( $data['general'] );
+                       $pageModulesJson = $this->context->encodeJson( $data['general'] );
                        $script .= <<<JAVASCRIPT
 RLPAGEMODULES = {$pageModulesJson};
 JAVASCRIPT;
@@ -478,7 +478,7 @@ JAVASCRIPT;
                                                        ] );
                                                } else {
                                                        $chunk = ResourceLoader::makeInlineScript(
-                                                               'mw.loader.load(' . ResourceLoader::encodeJsonForScript( $url ) . ');',
+                                                               'mw.loader.load(' . $mainContext->encodeJson( $url ) . ');',
                                                                $nonce
                                                        );
                                                }
index 95b8ff0..b9a7659 100644 (file)
@@ -405,7 +405,7 @@ class ResourceLoaderContext implements MessageLocalizer {
        /**
         * Get the request base parameters, omitting any defaults.
         *
-        * @internal For internal use by ResourceLoaderStartUpModule only
+        * @internal For use by ResourceLoaderStartUpModule only
         * @return array
         */
        public function getReqBase() {
@@ -421,4 +421,32 @@ class ResourceLoaderContext implements MessageLocalizer {
                }
                return $reqBase;
        }
+
+       /**
+        * Wrapper around json_encode that avoids needless escapes,
+        * and pretty-prints in debug mode.
+        *
+        * @internal
+        * @param mixed $data
+        * @return string|false JSON string, false on error
+        */
+       public function encodeJson( $data ) {
+               // Keep output as small as possible by disabling needless escape modes
+               // that PHP uses by default.
+               // However, while most module scripts are only served on HTTP responses
+               // for JavaScript, some modules can also be embedded in the HTML as inline
+               // scripts. This, and the fact that we sometimes need to export strings
+               // containing user-generated content and labels that may genuinely contain
+               // a sequences like "</script>", we need to encode either '/' or '<'.
+               // By default PHP escapes '/'. Let's escape '<' instead which is less common
+               // and allows URLs to mostly remain readable.
+               $jsonFlags = JSON_UNESCAPED_SLASHES |
+                       JSON_UNESCAPED_UNICODE |
+                       JSON_HEX_TAG |
+                       JSON_HEX_AMP;
+               if ( $this->getDebug() ) {
+                       $jsonFlags |= JSON_PRETTY_PRINT;
+               }
+               return json_encode( $data, $jsonFlags );
+       }
 }
index f2d0856..6c21e4b 100644 (file)
@@ -383,7 +383,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         * @return string|array JavaScript code for $context, or package files data structure
         */
        public function getScript( ResourceLoaderContext $context ) {
-               $deprecationScript = $this->getDeprecationInformation();
+               $deprecationScript = $this->getDeprecationInformation( $context );
                if ( $this->packageFiles !== null ) {
                        $packageFiles = $this->getPackageFiles( $context );
                        if ( $deprecationScript ) {
index c0a0921..637d6d2 100644 (file)
@@ -54,8 +54,8 @@ class ResourceLoaderLanguageDataModule extends ResourceLoaderFileModule {
        public function getScript( ResourceLoaderContext $context ) {
                return parent::getScript( $context )
                        . 'mw.language.setData('
-                       . ResourceLoader::encodeJsonForScript( $context->getLanguage() ) . ','
-                       . ResourceLoader::encodeJsonForScript( $this->getData( $context ) )
+                       . $context->encodeJson( $context->getLanguage() ) . ','
+                       . $context->encodeJson( $this->getData( $context ) )
                        . ');';
        }
 
index ed2d09c..38084bf 100644 (file)
@@ -135,9 +135,13 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
        /**
         * Get JS representing deprecation information for the current module if available
         *
+        * @param ResourceLoaderContext|null $context Missing $context is deprecated in 1.34
         * @return string JavaScript code
         */
-       public function getDeprecationInformation() {
+       public function getDeprecationInformation( ResourceLoaderContext $context = null ) {
+               if ( $context === null ) {
+                       wfDeprecated( __METHOD__ . ' without a ResourceLoader context', '1.34' );
+               }
                $deprecationInfo = $this->deprecated;
                if ( $deprecationInfo ) {
                        $name = $this->getName();
@@ -145,7 +149,10 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
                        if ( is_string( $deprecationInfo ) ) {
                                $warning .= "\n" . $deprecationInfo;
                        }
-                       return 'mw.log.warn(' . ResourceLoader::encodeJsonForScript( $warning ) . ');';
+                       if ( $context === null ) {
+                               return 'mw.log.warn(' . ResourceLoader::encodeJsonForScript( $warning ) . ');';
+                       }
+                       return 'mw.log.warn(' . $context->encodeJson( $warning ) . ');';
                } else {
                        return '';
                }
index 9f583a5..3191057 100644 (file)
@@ -307,7 +307,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        }
 
                        $skipFunction = $module->getSkipFunction();
-                       if ( $skipFunction !== null && !ResourceLoader::inDebugMode() ) {
+                       if ( $skipFunction !== null && !$context->getDebug() ) {
                                $skipFunction = ResourceLoader::filter( 'minify-js', $skipFunction );
                        }
 
@@ -323,7 +323,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                self::compileUnresolvedDependencies( $registryData );
 
                // Register sources
-               $out .= ResourceLoader::makeLoaderSourcesScript( $resourceLoader->getSources() );
+               $out .= ResourceLoader::makeLoaderSourcesScript( $context, $resourceLoader->getSources() );
 
                // Figure out the different call signatures for mw.loader.register
                $registrations = [];
@@ -341,10 +341,10 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                }
 
                // Register modules
-               $out .= "\n" . ResourceLoader::makeLoaderRegisterScript( $registrations );
+               $out .= "\n" . ResourceLoader::makeLoaderRegisterScript( $context, $registrations );
 
                if ( $states ) {
-                       $out .= "\n" . ResourceLoader::makeLoaderStateScript( $states );
+                       $out .= "\n" . ResourceLoader::makeLoaderStateScript( $context, $states );
                }
 
                return $out;
@@ -423,23 +423,23 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
 
                // Perform replacements for mediawiki.js
                $mwLoaderPairs = [
-                       '$VARS.reqBase' => ResourceLoader::encodeJsonForScript( $context->getReqBase() ),
-                       '$VARS.baseModules' => ResourceLoader::encodeJsonForScript( $this->getBaseModules() ),
-                       '$VARS.maxQueryLength' => ResourceLoader::encodeJsonForScript(
+                       '$VARS.reqBase' => $context->encodeJson( $context->getReqBase() ),
+                       '$VARS.baseModules' => $context->encodeJson( $this->getBaseModules() ),
+                       '$VARS.maxQueryLength' => $context->encodeJson(
                                $conf->get( 'ResourceLoaderMaxQueryLength' )
                        ),
                        // The client-side module cache can be disabled by site configuration.
                        // It is also always disabled in debug mode.
-                       '$VARS.storeEnabled' => ResourceLoader::encodeJsonForScript(
+                       '$VARS.storeEnabled' => $context->encodeJson(
                                $conf->get( 'ResourceLoaderStorageEnabled' ) && !$context->getDebug()
                        ),
-                       '$VARS.wgLegacyJavaScriptGlobals' => ResourceLoader::encodeJsonForScript(
+                       '$VARS.wgLegacyJavaScriptGlobals' => $context->encodeJson(
                                $conf->get( 'LegacyJavaScriptGlobals' )
                        ),
-                       '$VARS.storeKey' => ResourceLoader::encodeJsonForScript( $this->getStoreKey() ),
-                       '$VARS.storeVary' => ResourceLoader::encodeJsonForScript( $this->getStoreVary( $context ) ),
-                       '$VARS.groupUser' => ResourceLoader::encodeJsonForScript( $this->getGroupId( 'user' ) ),
-                       '$VARS.groupPrivate' => ResourceLoader::encodeJsonForScript( $this->getGroupId( 'private' ) ),
+                       '$VARS.storeKey' => $context->encodeJson( $this->getStoreKey() ),
+                       '$VARS.storeVary' => $context->encodeJson( $this->getStoreVary( $context ) ),
+                       '$VARS.groupUser' => $context->encodeJson( $this->getGroupId( 'user' ) ),
+                       '$VARS.groupPrivate' => $context->encodeJson( $this->getGroupId( 'private' ) ),
                ];
                $profilerStubs = [
                        '$CODE.profileExecuteStart();' => 'mw.loader.profiler.onExecuteStart( module );',
@@ -458,7 +458,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
 
                // Perform string replacements for startup.js
                $pairs = [
-                       '$VARS.configuration' => ResourceLoader::encodeJsonForScript(
+                       '$VARS.configuration' => $context->encodeJson(
                                $this->getConfigSettings( $context )
                        ),
                        // Raw JavaScript code (not JSON)
index 61cff82..de82502 100644 (file)
@@ -41,7 +41,7 @@ class ResourceLoaderUserDefaultsModule extends ResourceLoaderModule {
         */
        public function getScript( ResourceLoaderContext $context ) {
                return 'mw.user.options.set('
-                       . ResourceLoader::encodeJsonForScript( User::getDefaultOptions() )
+                       . $context->encodeJson( User::getDefaultOptions() )
                        . ');';
        }
 }
index ecbb501..059a9b9 100644 (file)
@@ -54,7 +54,7 @@ class ResourceLoaderUserOptionsModule extends ResourceLoaderModule {
                // Use FILTER_NOMIN annotation to prevent needless minification and caching (T84960).
                return ResourceLoader::FILTER_NOMIN
                        . 'mw.user.options.set('
-                       . ResourceLoader::encodeJsonForScript(
+                       . $context->encodeJson(
                                $context->getUserObj()->getOptions( User::GETOPTIONS_EXCLUDE_DEFAULTS )
                        )
                        . ');';
index 85c14cb..86012a0 100644 (file)
@@ -55,7 +55,7 @@ class ResourceLoaderUserTokensModule extends ResourceLoaderModule {
                // Use FILTER_NOMIN annotation to prevent needless minification and caching (T84960).
                return ResourceLoader::FILTER_NOMIN
                        . 'mw.user.tokens.set('
-                       . ResourceLoader::encodeJsonForScript( $this->contextUserTokens( $context ) )
+                       . $context->encodeJson( $this->contextUserTokens( $context ) )
                        . ');';
        }
 
index 9bbf14d..0c3512a 100644 (file)
@@ -718,9 +718,9 @@ mw.loader.register([
         * @dataProvider provideRegistrations
         */
        public function testRegistrationsMinified( $modules ) {
-               $this->setMwGlobals( 'wgResourceLoaderDebug', false );
-
-               $context = $this->getResourceLoaderContext();
+               $context = $this->getResourceLoaderContext( [
+                       'debug' => 'false',
+               );
                $rl = $context->getResourceLoader();
                $rl->register( $modules );
                $module = new ResourceLoaderStartUpModule();
@@ -743,7 +743,9 @@ mw.loader.register([
         * @dataProvider provideRegistrations
         */
        public function testRegistrationsUnminified( $modules ) {
-               $context = $this->getResourceLoaderContext();
+               $context = $this->getResourceLoaderContext( [
+                       'debug' => 'true',
+               ] );
                $rl = $context->getResourceLoader();
                $rl->register( $modules );
                $module = new ResourceLoaderStartUpModule();
index 94e3461..e728ad5 100644 (file)
@@ -518,13 +518,14 @@ END
                        'wrap' => true,
                        'styles' => [], 'templates' => [], 'messages' => new XmlJsCode( '{}' ), 'packageFiles' => [],
                ];
-               ResourceLoader::clearCache();
-               $this->setMwGlobals( 'wgResourceLoaderDebug', true );
-
                $rl = TestingAccessWrapper::newFromClass( ResourceLoader::class );
+               $context = new ResourceLoaderContext( new EmptyResourceLoader(), new FauxRequest( [
+                       'debug' => 'true',
+               ] ) );
                $this->assertEquals(
                        $case['expected'],
                        $rl->makeLoaderImplementScript(
+                               $context,
                                $case['name'],
                                ( $case['wrap'] && is_string( $case['scripts'] ) )
                                        ? new XmlJsCode( $case['scripts'] )
@@ -543,7 +544,9 @@ END
        public function testMakeLoaderImplementScriptInvalid() {
                $this->setExpectedException( MWException::class, 'Invalid scripts error' );
                $rl = TestingAccessWrapper::newFromClass( ResourceLoader::class );
+               $context = new ResourceLoaderContext( new EmptyResourceLoader(), new FauxRequest() );
                $rl->makeLoaderImplementScript(
+                       $context,
                        'test', // name
                        123, // scripts
                        null, // styles
@@ -557,6 +560,9 @@ END
         * @covers ResourceLoader::makeLoaderRegisterScript
         */
        public function testMakeLoaderRegisterScript() {
+               $context = new ResourceLoaderContext( new EmptyResourceLoader(), new FauxRequest( [
+                       'debug' => 'true',
+               ] ) );
                $this->assertEquals(
                        'mw.loader.register([
     [
@@ -564,7 +570,7 @@ END
         "1234567"
     ]
 ]);',
-                       ResourceLoader::makeLoaderRegisterScript( [
+                       ResourceLoader::makeLoaderRegisterScript( $context, [
                                [ 'test.name', '1234567' ],
                        ] ),
                        'Nested array parameter'
@@ -600,7 +606,7 @@ END
         "return true;"
     ]
 ]);',
-                       ResourceLoader::makeLoaderRegisterScript( [
+                       ResourceLoader::makeLoaderRegisterScript( $context, [
                                [ 'test.foo', '100' , [], null, null ],
                                [ 'test.bar', '200', [ 'test.unknown' ], null ],
                                [ 'test.baz', '300', [ 'test.quux', 'test.foo' ], null ],
@@ -614,31 +620,34 @@ END
         * @covers ResourceLoader::makeLoaderSourcesScript
         */
        public function testMakeLoaderSourcesScript() {
+               $context = new ResourceLoaderContext( new EmptyResourceLoader(), new FauxRequest( [
+                       'debug' => 'true',
+               ] ) );
                $this->assertEquals(
                        'mw.loader.addSource({
     "local": "/w/load.php"
 });',
-                       ResourceLoader::makeLoaderSourcesScript( 'local', '/w/load.php' )
+                       ResourceLoader::makeLoaderSourcesScript( $context, 'local', '/w/load.php' )
                );
                $this->assertEquals(
                        'mw.loader.addSource({
     "local": "/w/load.php"
 });',
-                       ResourceLoader::makeLoaderSourcesScript( [ 'local' => '/w/load.php' ] )
+                       ResourceLoader::makeLoaderSourcesScript( $context, [ 'local' => '/w/load.php' ] )
                );
                $this->assertEquals(
                        'mw.loader.addSource({
     "local": "/w/load.php",
     "example": "https://example.org/w/load.php"
 });',
-                       ResourceLoader::makeLoaderSourcesScript( [
+                       ResourceLoader::makeLoaderSourcesScript( $context, [
                                'local' => '/w/load.php',
                                'example' => 'https://example.org/w/load.php'
                        ] )
                );
                $this->assertEquals(
                        'mw.loader.addSource([]);',
-                       ResourceLoader::makeLoaderSourcesScript( [] )
+                       ResourceLoader::makeLoaderSourcesScript( $context, [] )
                );
        }