Make WordPress Core

Changeset 62379


Ignore:
Timestamp:
05/19/2026 12:23:04 PM (3 months ago)
Author:
ellatrix
Message:

Script Loader: Warn when classic scripts with module dependencies lack footer/defer.

A classic script with module_dependencies may be evaluated before the script modules import map is printed if it loads blocking in the document head, causing a "Failed to resolve module specifier" error on dynamic imports.

  • Trigger _doing_it_wrong() from _wp_scripts_add_args_data() when a classic script provides module_dependencies without setting in_footer to true or using a defer loading strategy, and document this requirement in the wp_register_script() and wp_enqueue_script() docblocks.
  • Remove the module_dependencies arg from the wp-codemirror script registration in favor of passing the espree module URL directly through wp_get_code_editor_settings(). This avoids registering espree as a publicly-available script module when it is only ever used internally as a private implementation detail of the code editor.
  • Add a console.warn() in wp.codeEditor.initialize() when invoked before DOMContentLoaded, so developers are alerted if the function is called too early for the import map to have been parsed.
  • Add PHPStan types which were missing when module_dependencies were initially introduced.
  • Harden WP_Scripts::add_data() against non-string strategy values being passed to sprintf().

Developed in https://github.com/WordPress/wordpress-develop/pull/11788

Follow-up to r61587.

Reviewed by jonsurrell.
Merges [62368] to the 7.0 branch.
Props khokansardar, westonruter, jonsurrell, jorbin.
See #61500, #64238.
Fixes #65165.

Location:
branches/7.0
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • branches/7.0

  • branches/7.0/src/js/_enqueues/lib/codemirror/javascript-lint.js

    r61800 r62379  
    3131 * @property {boolean} [module] - "This option informs JSHint that the input code describes an ECMAScript 6 module. All module code is interpreted as strict mode code."
    3232 * @property {'implied'} [strict] - "This option requires the code to run in ECMAScript 5's strict mode."
     33 * @property {string} [espreeModuleUrl] - The URL to the espree script module.
    3334 */
    3435
     
    4344 */
    4445async function validator( text, options ) {
     46        if ( ! options.espreeModuleUrl ) {
     47                return [];
     48        }
     49
    4550        const errors = /** @type {CodeMirrorLintError[]} */ [];
    4651        try {
    47                 const espree = await import( /* webpackIgnore: true */ 'espree' );
     52                const espree = await import( /* webpackIgnore: true */ options.espreeModuleUrl );
    4853                espree.parse( text, {
    4954                        ...getEspreeOptions( options ),
  • branches/7.0/src/js/_enqueues/wp/code-editor.js

    r61800 r62379  
    22 * @output wp-admin/js/code-editor.js
    33 */
     4
     5/* global console */
    46
    57/* eslint-env es2020 */
     
    413415         */
    414416        wp.codeEditor.initialize = function initialize( textarea, settings ) {
     417                if ( document.readyState === 'loading' ) {
     418                        console.warn( 'wp.codeEditor.initialize() ran too early. Invoke this function in a `DOMContentLoaded` event listener.' );
     419                }
     420
    415421                let $textarea;
    416422                if ( 'string' === typeof textarea ) {
  • branches/7.0/src/wp-includes/class-wp-scripts.php

    r61927 r62379  
    886886                                                /* translators: 1: $strategy, 2: $handle */
    887887                                                __( 'Invalid strategy `%1$s` defined for `%2$s` during script registration.' ),
    888                                                 $value,
     888                                                is_string( $value ) ? $value : gettype( $value ),
    889889                                                $handle
    890890                                        ),
     
    898898                                                /* translators: 1: $strategy, 2: $handle */
    899899                                                __( 'Cannot supply a strategy `%1$s` for script `%2$s` because it is an alias (it lacks a `src` value).' ),
    900                                                 $value,
     900                                                is_string( $value ) ? $value : gettype( $value ),
    901901                                                $handle
    902902                                        ),
  • branches/7.0/src/wp-includes/functions.wp-scripts.php

    r61587 r62379  
    7272 * Adds the data for the recognized args and warns for unrecognized args.
    7373 *
     74 * @see wp_enqueue_script()
     75 * @see wp_register_script()
     76 *
    7477 * @ignore
    7578 * @since 7.0.0
     
    7881 * @param string     $handle     Script handle.
    7982 * @param array      $args       Array of extra args for the script.
    80  */
    81 function _wp_scripts_add_args_data( WP_Scripts $wp_scripts, string $handle, array $args ) {
     83 *
     84 * @phpstan-param non-empty-string $handle
     85 * @phpstan-param array{
     86 *     in_footer?: bool,
     87 *     strategy?: 'async'|'defer',
     88 *     fetchpriority?: 'low'|'auto'|'high',
     89 *     module_dependencies?: array<non-empty-string|array{ id: non-empty-string, ... }>,
     90 * } $args
     91 */
     92function _wp_scripts_add_args_data( WP_Scripts $wp_scripts, string $handle, array $args ): void {
    8293        $allowed_keys = array( 'strategy', 'in_footer', 'fetchpriority', 'module_dependencies' );
    8394        $unknown_keys = array_diff( array_keys( $args ), $allowed_keys );
    8495        if ( ! empty( $unknown_keys ) ) {
    8596                $trace         = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 2 );
    86                 $function_name = ( $trace[1]['class'] ?? '' ) . ( $trace[1]['type'] ?? '' ) . $trace[1]['function'];
     97                $function_name = ( $trace[1]['class'] ?? '' ) . ( $trace[1]['type'] ?? '' ) . ( $trace[1]['function'] ?? __FUNCTION__ );
    8798                _doing_it_wrong(
    8899                        $function_name,
     
    98109        }
    99110
    100         if ( ! empty( $args['in_footer'] ) ) {
     111        $in_footer = ! empty( $args['in_footer'] );
     112        if ( $in_footer ) {
    101113                $wp_scripts->add_data( $handle, 'group', 1 );
    102114        }
     
    109121        if ( ! empty( $args['module_dependencies'] ) ) {
    110122                $wp_scripts->add_data( $handle, 'module_dependencies', $args['module_dependencies'] );
     123
     124                /*
     125                 * A classic script with module dependencies must either be printed in the
     126                 * footer or use the 'defer' loading strategy. Otherwise, the script may be
     127                 * evaluated before the script modules import map is printed, causing
     128                 * dynamic imports to fail with a "Failed to resolve module specifier" error.
     129                 */
     130                $is_deferred = 'defer' === ( $args['strategy'] ?? null );
     131                if ( ! $in_footer && ! $is_deferred ) {
     132                        $trace         = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 2 );
     133                        $function_name = ( $trace[1]['class'] ?? '' ) . ( $trace[1]['type'] ?? '' ) . ( $trace[1]['function'] ?? __FUNCTION__ );
     134                        _doing_it_wrong(
     135                                $function_name,
     136                                sprintf(
     137                                        /* translators: 1: 'module_dependencies', 2: Script handle, 3: 'in_footer', 4: 'strategy', 5: 'defer'. */
     138                                        __( 'When the %1$s arg is provided, the "%2$s" script must either be printed in the footer (%3$s set to true) or use a deferred loading %4$s (%5$s) so that the import map is printed before the script is evaluated.' ),
     139                                        '<code>module_dependencies</code>',
     140                                        $handle,
     141                                        '<code>in_footer</code>',
     142                                        '<code>strategy</code>',
     143                                        '<code>defer</code>'
     144                                ),
     145                                '7.0.0'
     146                        );
     147                }
    111148        }
    112149}
     
    205242 * @since 7.0.0 The $module_dependencies parameter of type string[] was added to the $args parameter of type array.
    206243 *
    207  * @param string                                                              $handle Name of the script. Should be unique.
    208  * @param string|false                                                        $src    Full URL of the script, or path of the script relative to the WordPress root directory.
    209  *                                                                                    If source is set to false, script is an alias of other scripts it depends on.
    210  * @param string[]                                                            $deps   Optional. An array of registered script handles this script depends on. Default empty array.
    211  * @param string|bool|null                                                    $ver    Optional. String specifying script version number, if it has one, which is added to the URL
    212  *                                                                                    as a query string for cache busting purposes. If version is set to false, a version
    213  *                                                                                    number is automatically added equal to current installed WordPress version.
    214  *                                                                                    If set to null, no version is added.
    215  * @param array<string, string|bool|array<string|array<string, string>>>|bool $args   {
     244 * @param string           $handle Name of the script. Should be unique.
     245 * @param string|false     $src    Full URL of the script, or path of the script relative to the WordPress root directory.
     246 *                                 If source is set to false, script is an alias of other scripts it depends on.
     247 * @param string[]         $deps   Optional. An array of registered script handles this script depends on. Default empty array.
     248 * @param string|bool|null $ver    Optional. String specifying script version number, if it has one, which is added to the URL
     249 *                                 as a query string for cache busting purposes. If version is set to false, a version
     250 *                                 number is automatically added equal to current installed WordPress version.
     251 *                                 If set to null, no version is added.
     252 * @param array|bool      $args   {
    216253 *     Optional. An array of extra args for the script. Default empty array.
    217254 *     Otherwise, it may be a boolean in which case it determines whether the script is printed in the footer. Default false.
    218255 *
    219  *     @type string                              $strategy            Optional. If provided, may be either 'defer' or 'async'.
    220  *     @type bool                                $in_footer           Optional. Whether to print the script in the footer. Default 'false'.
    221  *     @type string                              $fetchpriority       Optional. The fetch priority for the script. Default 'auto'.
    222  *     @type array<string|array<string, string>> $module_dependencies Optional. IDs for module dependencies loaded via dynamic import. Default empty array.
     256 *     @type string $strategy            Optional. If provided, may be either 'defer' or 'async'.
     257 *     @type bool   $in_footer           Optional. Whether to print the script in the footer. Default 'false'.
     258 *     @type string $fetchpriority       Optional. The fetch priority for the script. Default 'auto'.
     259 *     @type array  $module_dependencies Optional. IDs for module dependencies loaded via dynamic import. Default empty array.
    223260 *                                                                    For the full data format, see the `$deps` param of {@see wp_register_script_module()}.
     261 *                                                                    When provided, the script must either be printed in the footer (with
     262 *                                                                    `in_footer` set to true) or use a deferred loading `strategy` (`defer`),
     263 *                                                                    so that the script modules import map is printed before the script
     264 *                                                                    is evaluated. Otherwise dynamic imports may fail to resolve.
    224265 * }
    225266 * @return bool Whether the script has been registered. True on success, false on failure.
     267 *
     268 * @phpstan-param non-empty-string $handle
     269 * @phpstan-param non-empty-string|false $src
     270 * @phpstan-param non-empty-string[] $deps
     271 * @phpstan-param array{
     272 *     in_footer?: bool,
     273 *     strategy?: 'async'|'defer',
     274 *     fetchpriority?: 'low'|'auto'|'high',
     275 *     module_dependencies?: array<non-empty-string|array{ id: non-empty-string, ... }>,
     276 * }|bool $args
    226277 */
    227278function wp_register_script( $handle, $src, $deps = array(), $ver = false, $args = array() ) {
     
    387438 * @since 7.0.0 The $module_dependencies parameter of type string[] was added to the $args parameter of type array.
    388439 *
    389  * @param string                                                              $handle Name of the script. Should be unique.
    390  * @param string                                                              $src    Full URL of the script, or path of the script relative to the WordPress root directory.
    391  *                                                                                    Default empty.
    392  * @param string[]                                                            $deps   Optional. An array of registered script handles this script depends on. Default empty array.
    393  * @param string|bool|null                                                    $ver    Optional. String specifying script version number, if it has one, which is added to the URL
    394  *                                                                                    as a query string for cache busting purposes. If version is set to false, a version
    395  *                                                                                    number is automatically added equal to current installed WordPress version.
    396  *                                                                                    If set to null, no version is added.
    397  * @param array<string, string|bool|array<string|array<string, string>>>|bool $args {
     440 * @param string           $handle Name of the script. Should be unique.
     441 * @param string           $src    Full URL of the script, or path of the script relative to the WordPress root directory.
     442 *                                 Default empty.
     443 * @param string[]         $deps   Optional. An array of registered script handles this script depends on. Default empty array.
     444 * @param string|bool|null $ver    Optional. String specifying script version number, if it has one, which is added to the URL
     445 *                                 as a query string for cache busting purposes. If version is set to false, a version
     446 *                                 number is automatically added equal to current installed WordPress version.
     447 *                                 If set to null, no version is added.
     448 * @param array|bool $args {
    398449 *     Optional. An array of extra args for the script. Default empty array.
    399450 *     Otherwise, it may be a boolean in which case it determines whether the script is printed in the footer. Default false.
    400451 *
    401  *     @type string                              $strategy            Optional. If provided, may be either 'defer' or 'async'.
    402  *     @type bool                                $in_footer           Optional. Whether to print the script in the footer. Default 'false'.
    403  *     @type string                              $fetchpriority       Optional. The fetch priority for the script. Default 'auto'.
    404  *     @type array<string|array<string, string>> $module_dependencies Optional. IDs for module dependencies loaded via dynamic import. Default empty array.
    405  *                                                                    For the full data format, see the `$deps` param of {@see wp_register_script_module()}.
     452 *     @type string $strategy            Optional. If provided, may be either 'defer' or 'async'.
     453 *     @type bool   $in_footer           Optional. Whether to print the script in the footer. Default 'false'.
     454 *     @type string $fetchpriority       Optional. The fetch priority for the script. Default 'auto'.
     455 *     @type array  $module_dependencies Optional. IDs for module dependencies loaded via dynamic import. Default empty array.
     456 *                                       For the full data format, see the `$deps` param of {@see wp_register_script_module()}.
     457 *                                       When provided, the script must either be printed in the footer (with
     458 *                                       `in_footer` set to true) or use a deferred loading `strategy` (`defer`),
     459 *                                       so that the script modules import map is printed before the script
     460 *                                       is evaluated. Otherwise dynamic imports may fail to resolve.
    406461 * }
     462 *
     463 * @phpstan-param non-empty-string $handle
     464 * @phpstan-param string $src
     465 * @phpstan-param non-empty-string[] $deps
     466 * @phpstan-param array{
     467 *     in_footer?: bool,
     468 *     strategy?: 'async'|'defer',
     469 *     fetchpriority?: 'low'|'auto'|'high',
     470 *     module_dependencies?: array<non-empty-string|array{ id: non-empty-string, ... }>,
     471 * }|bool $args
    407472 */
    408473function wp_enqueue_script( $handle, $src = '', $deps = array(), $ver = false, $args = array() ) {
     
    412477
    413478        if ( $src || ! empty( $args ) ) {
     479                /** @var array{ 0: non-empty-string, 1?: string } $_handle */
    414480                $_handle = explode( '?', $handle );
    415481                if ( ! is_array( $args ) ) {
  • branches/7.0/src/wp-includes/general-template.php

    r62036 r62379  
    41564156                ),
    41574157                'jshint'     => array(
    4158                         'esversion' => 11,
    4159                         'module'    => str_ends_with( $args['file'] ?? '', '.mjs' ),
     4158                        'esversion'       => 11,
     4159                        'module'          => str_ends_with( $args['file'] ?? '', '.mjs' ),
     4160
     4161                        // This script module URL is intentionally referenced here instead of registering an espree script module
     4162                        // in wp_default_script_modules(). This is a first stab at a core-only private module.
     4163                        'espreeModuleUrl' => add_query_arg( 'ver', '9.6.1', includes_url( 'js/codemirror/espree.min.js' ) ),
    41604164
    41614165                        // The following JSHint *linting rule* options are copied from
     
    41644168                        // are honored by the Espree-based integration, but these linting-rule options are not interpreted by Espree
    41654169                        // and are kept only for compatibility/documentation with the original JSHint configuration.
    4166                         'boss'      => true,
    4167                         'curly'     => true,
    4168                         'eqeqeq'    => true,
    4169                         'eqnull'    => true,
    4170                         'expr'      => true,
    4171                         'immed'     => true,
    4172                         'noarg'     => true,
    4173                         'nonbsp'    => true,
    4174                         'quotmark'  => 'single',
    4175                         'undef'     => true,
    4176                         'unused'    => true,
    4177                         'browser'   => true,
    4178                         'globals'   => array(
     4170                        'boss'            => true,
     4171                        'curly'           => true,
     4172                        'eqeqeq'          => true,
     4173                        'eqnull'          => true,
     4174                        'expr'            => true,
     4175                        'immed'           => true,
     4176                        'noarg'           => true,
     4177                        'nonbsp'          => true,
     4178                        'quotmark'        => 'single',
     4179                        'undef'           => true,
     4180                        'unused'          => true,
     4181                        'browser'         => true,
     4182                        'globals'         => array(
    41794183                                '_'                 => false,
    41804184                                'Backbone'          => false,
  • branches/7.0/src/wp-includes/script-loader.php

    r62373 r62379  
    12011201
    12021202        $scripts->add( 'wp-codemirror', '/wp-includes/js/codemirror/codemirror.min.js', array(), '5.65.20' );
    1203         did_action( 'init' ) && $scripts->add_data( 'wp-codemirror', 'module_dependencies', array( 'espree' ) );
    12041203        $scripts->add( 'csslint', '/wp-includes/js/codemirror/csslint.js', array(), '1.0.5' );
    1205         $scripts->add( 'esprima', '/wp-includes/js/codemirror/esprima.js', array(), '4.0.1' ); // Deprecated. Use 'espree' script module.
     1204        $scripts->add( 'esprima', '/wp-includes/js/codemirror/esprima.js', array(), '4.0.1' ); // Deprecated.
    12061205        $scripts->add( 'jshint', '/wp-includes/js/codemirror/fakejshint.js', array( 'esprima' ), '2.9.5' ); // Deprecated.
    12071206        $scripts->add( 'jsonlint', '/wp-includes/js/codemirror/jsonlint.js', array(), '1.6.3' );
  • branches/7.0/src/wp-includes/script-modules.php

    r62286 r62379  
    220220                wp_register_script_module( $script_module_id, $path, $module_deps, $script_module_data['version'], $args );
    221221        }
    222 
    223         wp_register_script_module(
    224                 'espree',
    225                 includes_url( 'js/codemirror/espree.min.js' ),
    226                 array(),
    227                 '9.6.1'
    228         );
    229222}
    230223
  • branches/7.0/tests/phpunit/includes/abstract-testcase.php

    r61604 r62379  
    1919        protected $caught_deprecated       = array();
    2020        protected $expected_doing_it_wrong = array();
    21         protected $caught_doing_it_wrong   = array();
     21
     22        /** @var non-empty-string[] */
     23        protected $caught_doing_it_wrong = array();
    2224
    2325        protected static $hooks_saved = array();
  • branches/7.0/tests/phpunit/tests/dependencies/scripts.php

    r61927 r62379  
    99 * @covers ::wp_add_inline_script
    1010 * @covers ::wp_set_script_translations
     11 *
     12 * @phpstan-type ScriptArgs array{
     13 *     in_footer?: bool,
     14 *     strategy?: 'async'|'defer',
     15 *     fetchpriority?: 'low'|'auto'|'high',
     16 *     module_dependencies?: array<non-empty-string|array{ id: non-empty-string, ... }>,
     17 * }
     18 * @phpstan-type WpEnqueueScriptArgs array{
     19 *     0: non-empty-string, // $handle
     20 *     1?: non-empty-string, // $src
     21 *     2?: non-empty-string[], // $deps
     22 *     3?: null|bool|string, // $version
     23 *     4?: ScriptArgs,
     24 * }
    1125 */
    1226class Tests_Dependencies_Scripts extends WP_UnitTestCase {
     
    13931407                                'expected' => true,
    13941408                                'stored'   => array( 'valid', array( 'id' => 'valid2' ) ),
     1409                        ),
     1410                );
     1411        }
     1412
     1413        /**
     1414         * Tests that registering a script with `module_dependencies` triggers `_doing_it_wrong`
     1415         * when the script is not printed in the footer and does not use the `defer` strategy.
     1416         *
     1417         * @ticket 65165
     1418         *
     1419         * @covers ::wp_register_script
     1420         * @covers ::wp_enqueue_script
     1421         * @covers ::_wp_scripts_add_args_data
     1422         *
     1423         * @dataProvider data_module_dependencies_require_footer_or_defer
     1424         *
     1425         * @param callable-string $function_name Function name to call.
     1426         * @param array           $args          Arguments to pass to the function.
     1427         * @param bool            $should_warn   Whether the call is expected to trigger a `_doing_it_wrong` warning.
     1428         *
     1429         * @phpstan-param WpEnqueueScriptArgs $args
     1430         */
     1431        public function test_module_dependencies_require_footer_or_defer( string $function_name, array $args, bool $should_warn ): void {
     1432                if ( $should_warn ) {
     1433                        $this->setExpectedIncorrectUsage( $function_name );
     1434                }
     1435
     1436                call_user_func_array( $function_name, $args );
     1437
     1438                if ( $should_warn ) {
     1439                        $this->assertStringContainsString(
     1440                                'module_dependencies',
     1441                                $this->caught_doing_it_wrong[ $function_name ],
     1442                                'The _doing_it_wrong message should reference module_dependencies.'
     1443                        );
     1444                        $this->assertStringContainsString(
     1445                                'in_footer',
     1446                                $this->caught_doing_it_wrong[ $function_name ],
     1447                                'The _doing_it_wrong message should reference the in_footer requirement.'
     1448                        );
     1449                        $this->assertStringContainsString(
     1450                                'defer',
     1451                                $this->caught_doing_it_wrong[ $function_name ],
     1452                                'The _doing_it_wrong message should reference the defer strategy.'
     1453                        );
     1454                } else {
     1455                        $this->assertArrayNotHasKey(
     1456                                $function_name,
     1457                                $this->caught_doing_it_wrong,
     1458                                'No _doing_it_wrong warning should be triggered when in_footer is true or strategy is defer.'
     1459                        );
     1460                }
     1461        }
     1462
     1463        /**
     1464         * Data provider for {@see self::test_module_dependencies_require_footer_or_defer()}.
     1465         *
     1466         * @phpstan-return array<string, array{
     1467         *     function_name: callable-string,
     1468         *     args: WpEnqueueScriptArgs,
     1469         *     should_warn: bool,
     1470         * }>
     1471         */
     1472        public function data_module_dependencies_require_footer_or_defer(): array {
     1473                $base_args = array(
     1474                        '/script.js',
     1475                        array(),
     1476                        null,
     1477                );
     1478
     1479                return array(
     1480                        'register_blocking_warns'            => array(
     1481                                'function_name' => 'wp_register_script',
     1482                                'args'          => array_merge(
     1483                                        array( 'module-deps-blocking-register' ),
     1484                                        $base_args,
     1485                                        array(
     1486                                                array(
     1487                                                        'module_dependencies' => array( 'foo' ),
     1488                                                ),
     1489                                        )
     1490                                ),
     1491                                'should_warn'   => true,
     1492                        ),
     1493                        'enqueue_blocking_warns'             => array(
     1494                                'function_name' => 'wp_enqueue_script',
     1495                                'args'          => array_merge(
     1496                                        array( 'module-deps-blocking-enqueue' ),
     1497                                        $base_args,
     1498                                        array(
     1499                                                array(
     1500                                                        'module_dependencies' => array( 'foo' ),
     1501                                                ),
     1502                                        )
     1503                                ),
     1504                                'should_warn'   => true,
     1505                        ),
     1506                        'register_async_warns'               => array(
     1507                                'function_name' => 'wp_register_script',
     1508                                'args'          => array_merge(
     1509                                        array( 'module-deps-async-register' ),
     1510                                        $base_args,
     1511                                        array(
     1512                                                array(
     1513                                                        'module_dependencies' => array( 'foo' ),
     1514                                                        'strategy'            => 'async',
     1515                                                ),
     1516                                        )
     1517                                ),
     1518                                'should_warn'   => true,
     1519                        ),
     1520                        'enqueue_async_warns'                => array(
     1521                                'function_name' => 'wp_enqueue_script',
     1522                                'args'          => array_merge(
     1523                                        array( 'module-deps-async-enqueue' ),
     1524                                        $base_args,
     1525                                        array(
     1526                                                array(
     1527                                                        'module_dependencies' => array( 'foo' ),
     1528                                                        'strategy'            => 'async',
     1529                                                ),
     1530                                        )
     1531                                ),
     1532                                'should_warn'   => true,
     1533                        ),
     1534                        'register_in_footer_does_not_warn'   => array(
     1535                                'function_name' => 'wp_register_script',
     1536                                'args'          => array_merge(
     1537                                        array( 'module-deps-footer-register' ),
     1538                                        $base_args,
     1539                                        array(
     1540                                                array(
     1541                                                        'module_dependencies' => array( 'foo' ),
     1542                                                        'in_footer'           => true,
     1543                                                ),
     1544                                        )
     1545                                ),
     1546                                'should_warn'   => false,
     1547                        ),
     1548                        'enqueue_in_footer_does_not_warn'    => array(
     1549                                'function_name' => 'wp_enqueue_script',
     1550                                'args'          => array_merge(
     1551                                        array( 'module-deps-footer-enqueue' ),
     1552                                        $base_args,
     1553                                        array(
     1554                                                array(
     1555                                                        'module_dependencies' => array( 'foo' ),
     1556                                                        'in_footer'           => true,
     1557                                                ),
     1558                                        )
     1559                                ),
     1560                                'should_warn'   => false,
     1561                        ),
     1562                        'register_defer_does_not_warn'       => array(
     1563                                'function_name' => 'wp_register_script',
     1564                                'args'          => array_merge(
     1565                                        array( 'module-deps-defer-register' ),
     1566                                        $base_args,
     1567                                        array(
     1568                                                array(
     1569                                                        'module_dependencies' => array( 'foo' ),
     1570                                                        'strategy'            => 'defer',
     1571                                                ),
     1572                                        )
     1573                                ),
     1574                                'should_warn'   => false,
     1575                        ),
     1576                        'enqueue_defer_does_not_warn'        => array(
     1577                                'function_name' => 'wp_enqueue_script',
     1578                                'args'          => array_merge(
     1579                                        array( 'module-deps-defer-enqueue' ),
     1580                                        $base_args,
     1581                                        array(
     1582                                                array(
     1583                                                        'module_dependencies' => array( 'foo' ),
     1584                                                        'strategy'            => 'defer',
     1585                                                ),
     1586                                        )
     1587                                ),
     1588                                'should_warn'   => false,
     1589                        ),
     1590                        'register_footer_and_defer_no_warn'  => array(
     1591                                'function_name' => 'wp_register_script',
     1592                                'args'          => array_merge(
     1593                                        array( 'module-deps-footer-defer-register' ),
     1594                                        $base_args,
     1595                                        array(
     1596                                                array(
     1597                                                        'module_dependencies' => array( 'foo' ),
     1598                                                        'in_footer'           => true,
     1599                                                        'strategy'            => 'defer',
     1600                                                ),
     1601                                        )
     1602                                ),
     1603                                'should_warn'   => false,
     1604                        ),
     1605                        'register_no_module_deps_no_warn'    => array(
     1606                                'function_name' => 'wp_register_script',
     1607                                'args'          => array_merge(
     1608                                        array( 'no-module-deps-register' ),
     1609                                        $base_args,
     1610                                        array( array() )
     1611                                ),
     1612                                'should_warn'   => false,
     1613                        ),
     1614                        'register_empty_module_deps_no_warn' => array(
     1615                                'function_name' => 'wp_register_script',
     1616                                'args'          => array_merge(
     1617                                        array( 'empty-module-deps-register' ),
     1618                                        $base_args,
     1619                                        array(
     1620                                                array(
     1621                                                        'module_dependencies' => array(),
     1622                                                ),
     1623                                        )
     1624                                ),
     1625                                'should_warn'   => false,
    13951626                        ),
    13961627                );
     
    31703401                                'browser',
    31713402                                'globals',
     3403                                'espreeModuleUrl',
    31723404                        ),
    31733405                        array_keys( $wp_enqueue_code_editor['jshint'] )
     
    32533485                                'browser',
    32543486                                'globals',
     3487                                'espreeModuleUrl',
    32553488                        ),
    32563489                        array_keys( $wp_enqueue_code_editor['jshint'] )
     
    33503583                                'browser',
    33513584                                'globals',
     3585                                'espreeModuleUrl',
    33523586                        ),
    33533587                        array_keys( $wp_enqueue_code_editor['jshint'] )
     
    34443678                                'browser',
    34453679                                'globals',
     3680                                'espreeModuleUrl',
    34463681                        ),
    34473682                        array_keys( $wp_enqueue_code_editor['jshint'] )
  • branches/7.0/tests/phpunit/tests/script-modules/wpScriptModules.php

    r62286 r62379  
    20422042                        false,
    20432043                        array(
     2044                                'strategy'            => 'defer',
    20442045                                'module_dependencies' => array(
    20452046                                        'example',
     
    21102111                        false,
    21112112                        array(
     2113                                'in_footer'           => true,
    21122114                                'module_dependencies' => array( 'classic-transitive-dependency' ),
    21132115                        )
     
    21192121                        false,
    21202122                        array(
     2123                                'in_footer'           => true,
    21212124                                'module_dependencies' => array( 'not-enqueued' ),
    21222125                        )
     
    21542157                        null,
    21552158                        array(
     2159                                'strategy'            => 'defer',
    21562160                                'module_dependencies' => array( 'does-not-exist' ),
    21572161                        )
Note: See TracChangeset for help on using the changeset viewer.