resourceloader: Move per-page function calls to startup.js
authorTimo Tijhof <krinklemail@gmail.com>
Wed, 8 May 2019 17:24:07 +0000 (18:24 +0100)
committerCatrope <roan@wikimedia.org>
Wed, 8 May 2019 21:23:59 +0000 (21:23 +0000)
Turn these embedded function calls into variable declarations,
later consumed by startup.js.

This has a few benefits:

* Variables can be declared immediately, without needing to
  defer it to after mw.loader arrives from startup, via an RLQ
  callback. This makes the inline script simpler and a tiny
  bit smaller.

* By moving the actual function calls to startup.js, they could
  easily be re-arranged in the future or migrated in other ways
  without needing to worry about HTML caching and keeping concurrent
  compatibility with both orders of execution.

Change-Id: I1c995a9572d9eb3201a565341c19bdf81ab00eff

includes/resourceloader/ResourceLoaderClientHtml.php
tests/phpunit/includes/resourceloader/ResourceLoaderClientHtmlTest.php

index ec408c7..6061fb5 100644 (file)
@@ -233,27 +233,43 @@ class ResourceLoaderClientHtml {
                $chunks = [];
 
                // Change "client-nojs" class to client-js. This allows easy toggling of UI components.
-               // This happens synchronously on every page view to avoid flashes of wrong content.
+               // This must happen synchronously on every page view to avoid flashes of wrong content.
                // See also #getDocumentAttributes() and /resources/src/startup.js.
-               $chunks[] = Html::inlineScript(
-                       'document.documentElement.className = document.documentElement.className'
-                       . '.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );',
-                       $nonce
-               );
+               $script = <<<JAVASCRIPT
+document.documentElement.className = document.documentElement.className
+       .replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );
+JAVASCRIPT;
 
-               // Inline RLQ: Set page variables
+               // Inline script: Declare mw.config variables for this page.
                if ( $this->config ) {
-                       $chunks[] = ResourceLoader::makeInlineScript(
-                               ResourceLoader::makeConfigSetScript( $this->config ),
-                               $nonce
-                       );
+                       $confJson = ResourceLoader::encodeJsonForScript( $this->config );
+                       $script .= <<<JAVASCRIPT
+RLCONF = {$confJson};
+JAVASCRIPT;
                }
 
-               // Inline RLQ: Initial module states
+               // Inline script: Declare initial module states for this page.
                $states = array_merge( $this->exemptStates, $data['states'] );
                if ( $states ) {
-                       $chunks[] = ResourceLoader::makeInlineScript(
-                               ResourceLoader::makeLoaderStateScript( $states ),
+                       $stateJson = ResourceLoader::encodeJsonForScript( $states );
+                       $script .= <<<JAVASCRIPT
+RLSTATE = {$stateJson};
+JAVASCRIPT;
+               }
+
+               // Inline script: Declare general modules to load on this page.
+               if ( $data['general'] ) {
+                       $pageModulesJson = ResourceLoader::encodeJsonForScript( $data['general'] );
+                       $script .= <<<JAVASCRIPT
+RLPAGEMODULES = {$pageModulesJson};
+JAVASCRIPT;
+               }
+
+               if ( $this->context->getDebug() ) {
+                       $chunks[] = Html::inlineScript( $script, $nonce );
+               } else {
+                       $chunks[] = Html::inlineScript(
+                               ResourceLoader::filter( 'minify-js', $script, [ 'cache' => false ] ),
                                $nonce
                        );
                }
@@ -267,17 +283,6 @@ class ResourceLoaderClientHtml {
                        );
                }
 
-               // Inline RLQ: Load general modules
-               if ( $data['general'] ) {
-                       $chunks[] = ResourceLoader::makeInlineScript(
-                               'RLPAGEMODULES='
-                                       . ResourceLoader::encodeJsonForScript( $data['general'] )
-                                       . ';'
-                                       . 'mw.loader.load(RLPAGEMODULES);',
-                               $nonce
-                       );
-               }
-
                // External stylesheets (only=styles)
                if ( $data['styles'] ) {
                        $chunks[] = $this->getLoad(
index 9ab3a2d..9e310d9 100644 (file)
@@ -107,12 +107,14 @@ Deprecation message.' ]
                ] );
 
                // phpcs:disable Generic.Files.LineLength
-               $expected = '<script>document.documentElement.className = document.documentElement.className.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );</script>' . "\n"
+               $expected = '<script>'
+                       . 'document.documentElement.className=document.documentElement.className.replace(/(^|\s)client-nojs(\s|$)/,"$1client-js$2");'
+                       . 'RLCONF={"key":"value"};'
+                       . 'RLSTATE={"test.exempt":"ready","test.private":"loading","test.styles.pure":"ready","test.styles.private":"ready","test.styles.deprecated":"ready"};'
+                       . 'RLPAGEMODULES=["test"];'
+                       . '</script>' . "\n"
                        . '<script>(window.RLQ=window.RLQ||[]).push(function(){'
-                       . 'mw.config.set({"key":"value"});'
-                       . 'mw.loader.state({"test.exempt":"ready","test.private":"loading","test.styles.pure":"ready","test.styles.private":"ready","test.styles.deprecated":"ready"});'
                        . 'mw.loader.implement("test.private@{blankVer}",null,{"css":[]});'
-                       . 'RLPAGEMODULES=["test"];mw.loader.load(RLPAGEMODULES);'
                        . '});</script>' . "\n"
                        . '<link rel="stylesheet" href="/w/load.php?lang=nl&amp;modules=test.styles.deprecated%2Cpure&amp;only=styles&amp;skin=fallback"/>' . "\n"
                        . '<style>.private{}</style>' . "\n"
@@ -133,7 +135,7 @@ Deprecation message.' ]
                );
 
                // phpcs:disable Generic.Files.LineLength
-               $expected = '<script>document.documentElement.className = document.documentElement.className.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );</script>' . "\n"
+               $expected = '<script>document.documentElement.className=document.documentElement.className.replace(/(^|\s)client-nojs(\s|$)/,"$1client-js$2");</script>' . "\n"
                        . '<script async="" src="/w/load.php?lang=nl&amp;modules=startup&amp;only=scripts&amp;skin=fallback&amp;target=example"></script>';
                // phpcs:enable
 
@@ -150,7 +152,7 @@ Deprecation message.' ]
                );
 
                // phpcs:disable Generic.Files.LineLength
-               $expected = '<script>document.documentElement.className = document.documentElement.className.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );</script>' . "\n"
+               $expected = '<script>document.documentElement.className=document.documentElement.className.replace(/(^|\s)client-nojs(\s|$)/,"$1client-js$2");</script>' . "\n"
                        . '<script async="" src="/w/load.php?lang=nl&amp;modules=startup&amp;only=scripts&amp;safemode=1&amp;skin=fallback"></script>';
                // phpcs:enable
 
@@ -167,7 +169,7 @@ Deprecation message.' ]
                );
 
                // phpcs:disable Generic.Files.LineLength
-               $expected = '<script>document.documentElement.className = document.documentElement.className.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2" );</script>' . "\n"
+               $expected = '<script>document.documentElement.className=document.documentElement.className.replace(/(^|\s)client-nojs(\s|$)/,"$1client-js$2");</script>' . "\n"
                        . '<script async="" src="/w/load.php?lang=nl&amp;modules=startup&amp;only=scripts&amp;skin=fallback"></script>';
                // phpcs:enable