From 13a042f8b74ecd20c42b86bb6cd987c9d66b7d5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Zi=C3=83=C2=B3=C3=85=E2=80=9Akowski?= Date: Mon, 12 Feb 2024 12:58:53 +0000 Subject: [PATCH] Script Modules API: Add deregister module function It was impossible to deregister a script module. It is changing to avoid problems for extenders that want to override any Core script module. Fixes #60463. Props cbravobernal, gziolo, mukesh27, youknowriad. git-svn-id: https://develop.svn.wordpress.org/trunk@57593 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-script-modules.php | 12 +++ src/wp-includes/script-modules.php | 11 +++ .../tests/script-modules/wpScriptModules.php | 73 +++++++++++++++++++ 3 files changed, 96 insertions(+) diff --git a/src/wp-includes/class-wp-script-modules.php b/src/wp-includes/class-wp-script-modules.php index b2413d0f24..6770597c1b 100644 --- a/src/wp-includes/class-wp-script-modules.php +++ b/src/wp-includes/class-wp-script-modules.php @@ -151,6 +151,18 @@ class WP_Script_Modules { unset( $this->enqueued_before_registered[ $id ] ); } + /** + * Removes a registered script module. + * + * @since 6.5.0 + * + * @param string $id The identifier of the script module. + */ + public function deregister( string $id ) { + unset( $this->registered[ $id ] ); + unset( $this->enqueued_before_registered[ $id ] ); + } + /** * Adds the hooks to print the import map, enqueued script modules and script * module preloads. diff --git a/src/wp-includes/script-modules.php b/src/wp-includes/script-modules.php index 2aff768bb3..f8efb9484b 100644 --- a/src/wp-includes/script-modules.php +++ b/src/wp-includes/script-modules.php @@ -112,3 +112,14 @@ function wp_enqueue_script_module( string $id, string $src = '', array $deps = a function wp_dequeue_script_module( string $id ) { wp_script_modules()->dequeue( $id ); } + +/** + * Deregisters the script module. + * + * @since 6.5.0 + * + * @param string $id The identifier of the script module. + */ +function wp_deregister_script_module( string $id ) { + wp_script_modules()->deregister( $id ); +} diff --git a/tests/phpunit/tests/script-modules/wpScriptModules.php b/tests/phpunit/tests/script-modules/wpScriptModules.php index 26ca916140..bc0a5a8559 100644 --- a/tests/phpunit/tests/script-modules/wpScriptModules.php +++ b/tests/phpunit/tests/script-modules/wpScriptModules.php @@ -126,6 +126,79 @@ class Tests_Script_Modules_WpScriptModules extends WP_UnitTestCase { $this->assertTrue( isset( $enqueued_script_modules['bar'] ) ); } + + /** + * Tests that a script module can be deregistered + * after being enqueued, and that will be removed + * from the enqueue list too. + * + * @ticket 60463 + * + * @covers ::register() + * @covers ::enqueue() + * @covers ::deregister() + * @covers ::get_enqueued_script_modules() + */ + public function test_wp_deregister_script_module() { + $this->script_modules->register( 'foo', '/foo.js' ); + $this->script_modules->register( 'bar', '/bar.js' ); + $this->script_modules->enqueue( 'foo' ); + $this->script_modules->enqueue( 'bar' ); + $this->script_modules->deregister( 'foo' ); // Dequeued. + + $enqueued_script_modules = $this->get_enqueued_script_modules(); + + $this->assertCount( 1, $enqueued_script_modules ); + $this->assertFalse( isset( $enqueued_script_modules['foo'] ) ); + $this->assertTrue( isset( $enqueued_script_modules['bar'] ) ); + } + + /** + * Tests that a script module is not deregistered + * if it has not been registered before, causing + * no errors. + * + * @ticket 60463 + * + * @covers ::deregister() + * @covers ::get_enqueued_script_modules() + */ + public function test_wp_deregister_unexistent_script_module() { + $this->script_modules->deregister( 'unexistent' ); + $enqueued_script_modules = $this->get_enqueued_script_modules(); + + $this->assertCount( 0, $enqueued_script_modules ); + $this->assertFalse( isset( $enqueued_script_modules['unexistent'] ) ); + } + + /** + * Tests that a script module is not deregistered + * if it has been deregistered previously, causing + * no errors. + * + * @ticket 60463 + * + * @covers ::get_enqueued_script_modules() + * @covers ::register() + * @covers ::deregister() + * @covers ::enqueue() + */ + public function test_wp_deregister_already_deregistered_script_module() { + $this->script_modules->register( 'foo', '/foo.js' ); + $this->script_modules->enqueue( 'foo' ); + $this->script_modules->deregister( 'foo' ); // Dequeued. + $enqueued_script_modules = $this->get_enqueued_script_modules(); + + $this->assertCount( 0, $enqueued_script_modules ); + $this->assertFalse( isset( $enqueued_script_modules['foo'] ) ); + + $this->script_modules->deregister( 'foo' ); // Dequeued. + $enqueued_script_modules = $this->get_enqueued_script_modules(); + + $this->assertCount( 0, $enqueued_script_modules ); + $this->assertFalse( isset( $enqueued_script_modules['foo'] ) ); + } + /** * Tests that a script module can be enqueued before it is registered, and will * be handled correctly once registered.