resourceloader: Add to debug mode the same 'jquery' clause as for prod
authorTimo Tijhof <krinklemail@gmail.com>
Wed, 8 Aug 2018 21:58:33 +0000 (22:58 +0100)
committerRoan Kattouw <roan.kattouw@gmail.com>
Wed, 8 Aug 2018 23:49:44 +0000 (16:49 -0700)
=== module.exports

Follows-up dec800968e, which added a clause for `window.$` inside runScript()
that ensures require/module.exports is not given to 'jquery'.

This commit adds the same clause to debug mode handling, which follows a
different code path. Without this, jquery.migrate.js execution throws from
`require('jquery')`, when viewing a page in debug mode.

=== mediawiki.legacy.wikibits

Before dec800968e, 'jquery' was a raw module and not allowed as dependency,
and before that commit base modules did not follow debug mode. Instead,
they were always combined in the same request (even in debug mode), with
only the order in the query string dictating their execution order.

After that commit, it is mandatory for base modules to express their
execution order through dependency links. This was done for 'mediawiki.base',
but forgotten for 'mediawiki.legacy.wikibits'. That module isn't used by
default, but becomes used when enabling $wgIncludeLegacyJavaScript, which
is off by default, but on for Wikimedia wikis.

Bug: T192623
Change-Id: Id4fbfee71deeb9528e8a622604d4cd972dd25d3b

resources/Resources.php
resources/src/startup/mediawiki.js

index a06a25f..c518399 100644 (file)
@@ -136,7 +136,9 @@ return [
                ],
        ],
 
-       /* jQuery */
+       /* Base modules */
+       // These modules' dependencies MUST also be included in StartUpModule::getBaseModules().
+       // These modules' dependencies MUST be dependency-free (having dependencies would cause recursion).
 
        'jquery' => [
                'scripts' => [
@@ -145,6 +147,20 @@ return [
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
+       'mediawiki.base' => [
+               'scripts' => [
+                       // 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',
+               ],
+               'dependencies' => 'jquery',
+               'targets' => [ 'desktop', 'mobile' ],
+       ],
+       'mediawiki.legacy.wikibits' => [
+               'scripts' => 'resources/src/mediawiki.legacy/wikibits.js',
+               'dependencies' => 'jquery',
+               'targets' => [ 'desktop', 'mobile' ],
+       ],
 
        /* jQuery Plugins */
 
@@ -831,18 +847,6 @@ return [
        ],
 
        /* MediaWiki */
-
-       'mediawiki.base' => [
-               'scripts' => [
-                       // 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',
-               ],
-               // - These dependencies MUST NOT also have dependencies (would cause recursion).
-               // - These dependencies MUST also be returned from StartUpModule::getBaseModules().
-               'dependencies' => 'jquery',
-               'targets' => [ 'desktop', 'mobile' ],
-       ],
        'mediawiki.apihelp' => [
                'styles' => 'resources/src/mediawiki.apihelp.css',
                'targets' => [ 'desktop' ],
@@ -2391,10 +2395,6 @@ return [
                        'resources/src/mediawiki.legacy/oldshared.css' => [ 'media' => 'screen' ]
                ],
        ],
-       'mediawiki.legacy.wikibits' => [
-               'scripts' => 'resources/src/mediawiki.legacy/wikibits.js',
-               'targets' => [ 'desktop', 'mobile' ],
-       ],
 
        /* MediaWiki UI */
 
index 351acc3..a2ba85f 100644 (file)
                        /**
                         * Queue the loading and execution of a script for a particular module.
                         *
+                        * This does for debug mode what runScript() does for production.
+                        *
                         * @private
                         * @param {string} src URL of the script
                         * @param {string} moduleName Name of currently executing module
                         */
                        function queueModuleScript( src, moduleName, callback ) {
                                pendingRequests.push( function () {
-                                       if ( hasOwn.call( registry, moduleName ) ) {
-                                               // Emulate runScript() part of execute()
+                                       // Keep in sync with execute()/runScript().
+                                       if ( moduleName !== 'jquery' && hasOwn.call( registry, moduleName ) ) {
                                                window.require = mw.loader.require;
                                                window.module = registry[ moduleName ].module;
                                        }
                                                if ( Array.isArray( script ) ) {
                                                        nestedAddScript( script, markModuleReady, 0 );
                                                } else if ( typeof script === 'function' ) {
-                                                       if ( window.$ ) {
-                                                               // Pass jQuery twice so that the signature of the closure which wraps
-                                                               // the script can bind both '$' and 'jQuery'.
-                                                               script( window.$, window.$, mw.loader.require, registry[ module ].module );
-                                                       } else {
+                                                       // Keep in sync with queueModuleScript() for debug mode
+                                                       if ( module === 'jquery' ) {
                                                                // This is a special case for when 'jquery' itself is being loaded.
                                                                // - The standard jquery.js distribution does not set `window.jQuery`
                                                                //   in CommonJS-compatible environments (Node.js, AMD, RequireJS, etc.).
                                                                //   in a CommonJS-compatible environment, will use require('jquery'),
                                                                //   but that can't work when we're still inside that module.
                                                                script();
+                                                       } else {
+                                                               // Pass jQuery twice so that the signature of the closure which wraps
+                                                               // the script can bind both '$' and 'jQuery'.
+                                                               script( window.$, window.$, mw.loader.require, registry[ module ].module );
                                                        }
                                                        markModuleReady();