From 322cc837246360df2ed11a44e33e58a77a504493 Mon Sep 17 00:00:00 2001 From: Luis Herranz Date: Wed, 10 Jan 2024 11:01:44 +0100 Subject: [PATCH] Allow wp_enqueue_module to also register modules --- src/wp-includes/class-wp-script-modules.php | 39 ++++++++- src/wp-includes/script-modules.php | 36 +++++++- .../tests/script-modules/wpScriptModules.php | 83 +++++++++++++++++++ 3 files changed, 152 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/class-wp-script-modules.php b/src/wp-includes/class-wp-script-modules.php index 22c4e29a286c8..4c98406929374 100644 --- a/src/wp-includes/class-wp-script-modules.php +++ b/src/wp-includes/class-wp-script-modules.php @@ -100,15 +100,48 @@ public function register( $module_id, $src, $deps = array(), $version = false ) * Marks the module to be enqueued in the page the next time * `prints_enqueued_modules` is called. * + * If a src is provided and the module has not been registered yet, it will be + * registered. + * * @since 6.5.0 * - * @param string $module_id The identifier of the module. + * @param string $module_id The identifier of the module. + * Should be unique. It will be used + * in the final import map. + * @param string $src Optional. Full URL of the module, + * or path of the module relative to + * the WordPress root directory. If + * it is provided and the module has + * not been registered yet, it will be + * registered. + * @param array $deps Optional. An array of module + * identifiers of the dependencies of + * this module. The dependencies can + * be strings or arrays. If they are + * arrays, they need an `id` key with + * the module identifier, and can + * contain an `import` key with either + * `static` or `dynamic`. By default, + * dependencies that don't contain an + * `import` key are considered static. + * @param string|false|null $version Optional. String specifying the + * module version number. Defaults to + * false. It is added to the URL as a + * query string for cache busting + * purposes. If $version is set to + * false, the version number is the + * currently installed WordPress + * version. If $version is set to + * null, no version is added. */ - public function enqueue( $module_id ) { + public function enqueue( $module_id, $src = null, $deps = array(), $version = false ) { if ( isset( $this->registered[ $module_id ] ) ) { $this->registered[ $module_id ]['enqueue'] = true; - } else { + } elseif ( ! is_string( $src ) ) { $this->enqueued_before_registered[ $module_id ] = true; + } else { + $this->register( $module_id, $src, $deps, $version ); + $this->registered[ $module_id ]['enqueue'] = true; } } diff --git a/src/wp-includes/script-modules.php b/src/wp-includes/script-modules.php index b3ef52870d489..87483233419e5 100644 --- a/src/wp-includes/script-modules.php +++ b/src/wp-includes/script-modules.php @@ -66,12 +66,42 @@ function wp_register_module( $module_id, $src, $deps = array(), $version = false /** * Marks the module to be enqueued in the page. * + * If a src is provided and the module has not been registered yet, it will be + * registered. + * * @since 6.5.0 * - * @param string $module_id The identifier of the module. + * @param string $module_id The identifier of the module. + * Should be unique. It will be used + * in the final import map. + * @param string $src Optional. Full URL of the module, + * or path of the module relative to + * the WordPress root directory. If + * it is provided and the module has + * not been registered yet, it will be + * registered. + * @param array $deps Optional. An array of module + * identifiers of the dependencies of + * this module. The dependencies can + * be strings or arrays. If they are + * arrays, they need an `id` key with + * the module identifier, and can + * contain an `import` key with either + * `static` or `dynamic`. By default, + * dependencies that don't contain an + * `import` key are considered static. + * @param string|false|null $version Optional. String specifying the + * module version number. Defaults to + * false. It is added to the URL as a + * query string for cache busting + * purposes. If $version is set to + * false, the version number is the + * currently installed WordPress + * version. If $version is set to + * null, no version is added. */ -function wp_enqueue_module( $module_id ) { - wp_modules()->enqueue( $module_id ); +function wp_enqueue_module( $module_id, $src = null, $deps = array(), $version = false ) { + wp_modules()->enqueue( $module_id, $src, $deps, $version ); } /** diff --git a/tests/phpunit/tests/script-modules/wpScriptModules.php b/tests/phpunit/tests/script-modules/wpScriptModules.php index e8947cb14e92b..2c82b592caacf 100644 --- a/tests/phpunit/tests/script-modules/wpScriptModules.php +++ b/tests/phpunit/tests/script-modules/wpScriptModules.php @@ -583,4 +583,87 @@ public function test_print_preloaded_modules_can_be_called_multiple_times() { $preloaded_modules = $this->get_preloaded_modules(); $this->assertCount( 0, $preloaded_modules ); } + + /** + * Tests that a module is not registered when calling enqueue without a valid + * src. + * + * @ticket 56313 + * + * @covers ::enqueue() + * @covers ::print_enqueued_modules() + */ + public function test_wp_enqueue_module_doesnt_register_without_a_valid_src() { + $this->modules->enqueue( 'foo' ); + + $enqueued_modules = $this->get_enqueued_modules(); + + $this->assertCount( 0, $enqueued_modules ); + $this->assertFalse( isset( $enqueued_modules['foo'] ) ); + } + + /** + * Tests that a module is registered when calling enqueue with a valid src. + * + * @ticket 56313 + * + * @covers ::enqueue() + * @covers ::print_enqueued_modules() + */ + public function test_wp_enqueue_module_registers_with_valid_src() { + $this->modules->enqueue( 'foo', '/foo.js' ); + + $enqueued_modules = $this->get_enqueued_modules(); + + $this->assertCount( 1, $enqueued_modules ); + $this->assertStringStartsWith( '/foo.js', $enqueued_modules['foo'] ); + } + + /** + * Tests that a module is registered when calling enqueue with a valid src the + * second time. + * + * @ticket 56313 + * + * @covers ::enqueue() + * @covers ::print_enqueued_modules() + */ + public function test_wp_enqueue_module_registers_with_valid_src_the_second_time() { + $this->modules->enqueue( 'foo' ); // Not valid src. + + $enqueued_modules = $this->get_enqueued_modules(); + + $this->assertCount( 0, $enqueued_modules ); + $this->assertFalse( isset( $enqueued_modules['foo'] ) ); + + $this->modules->enqueue( 'foo', '/foo.js' ); // Valid src. + + $enqueued_modules = $this->get_enqueued_modules(); + + $this->assertCount( 1, $enqueued_modules ); + $this->assertStringStartsWith( '/foo.js', $enqueued_modules['foo'] ); + } + + /** + * Tests that a module is registered with all the params when calling enqueue. + * + * @ticket 56313 + * + * @covers ::register() + * @covers ::enqueue() + * @covers ::print_enqueued_modules() + * @covers ::print_import_map() + */ + public function test_wp_enqueue_module_registers_all_params() { + $this->modules->enqueue( 'foo', '/foo.js', array( 'dep' ), '1.0' ); + $this->modules->register( 'dep', '/dep.js' ); + + $enqueued_modules = $this->get_enqueued_modules(); + $import_map = $this->get_import_map(); + + $this->assertCount( 1, $enqueued_modules ); + $this->assertEquals( '/foo.js?ver=1.0', $enqueued_modules['foo'] ); + $this->assertCount( 1, $import_map ); + $this->assertStringStartsWith( '/dep.js', $import_map['dep'] ); + } }