diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index 01cc2070ac779..22af83b55b5ae 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -129,6 +129,7 @@ function get_block_asset_url( $path ) { * * @since 5.5.0 * @since 6.1.0 Added `$index` parameter. + * @since 6.5.0 Added ability for reading a custom script handle from the block asset file. * * @param array $metadata Block metadata. * @param string $field_name Field name to pick from metadata. @@ -142,22 +143,21 @@ function register_block_script_handle( $metadata, $field_name, $index = 0 ) { return false; } - $script_handle = $metadata[ $field_name ]; - if ( is_array( $script_handle ) ) { - if ( empty( $script_handle[ $index ] ) ) { + $script_handle_or_path = $metadata[ $field_name ]; + if ( is_array( $script_handle_or_path ) ) { + if ( empty( $script_handle_or_path[ $index ] ) ) { return false; } - $script_handle = $script_handle[ $index ]; + $script_handle_or_path = $script_handle_or_path[ $index ]; } - $script_path = remove_block_asset_path_prefix( $script_handle ); - if ( $script_handle === $script_path ) { - return $script_handle; + $script_path = remove_block_asset_path_prefix( $script_handle_or_path ); + if ( $script_handle_or_path === $script_path ) { + return $script_handle_or_path; } $path = dirname( $metadata['file'] ); $script_asset_raw_path = $path . '/' . substr_replace( $script_path, '.asset.php', - strlen( '.js' ) ); - $script_handle = generate_block_asset_handle( $metadata['name'], $field_name, $index ); $script_asset_path = wp_normalize_path( realpath( $script_asset_raw_path ) ); @@ -177,6 +177,14 @@ function register_block_script_handle( $metadata, $field_name, $index = 0 ) { return false; } + $script_asset = require $script_asset_path; + $script_handle = isset( $script_asset['handle'] ) ? + $script_asset['handle'] : + generate_block_asset_handle( $metadata['name'], $field_name, $index ); + if ( wp_script_is( $script_handle, 'registered' ) ) { + return $script_handle; + } + $script_path_norm = wp_normalize_path( realpath( $path . '/' . $script_path ) ); $script_uri = get_block_asset_url( $script_path_norm ); @@ -185,13 +193,13 @@ function register_block_script_handle( $metadata, $field_name, $index = 0 ) { $script_args['strategy'] = 'defer'; } - $script_asset = require $script_asset_path; $script_dependencies = isset( $script_asset['dependencies'] ) ? $script_asset['dependencies'] : array(); + $block_version = ! $is_core_block && isset( $metadata['version'] ) ? $metadata['version'] : false; $result = wp_register_script( $script_handle, $script_uri, $script_dependencies, - isset( $script_asset['version'] ) ? $script_asset['version'] : false, + isset( $script_asset['version'] ) ? $script_asset['version'] : $block_version, $script_args ); if ( ! $result ) { diff --git a/tests/phpunit/data/blocks/notice/shared-script.asset.php b/tests/phpunit/data/blocks/notice/shared-script.asset.php new file mode 100644 index 0000000000000..d35471c73db2a --- /dev/null +++ b/tests/phpunit/data/blocks/notice/shared-script.asset.php @@ -0,0 +1,7 @@ + 'tests-my-shared-script', + 'dependencies' => array(), + 'version' => 'test', +); diff --git a/tests/phpunit/data/blocks/notice/shared-script.js b/tests/phpunit/data/blocks/notice/shared-script.js new file mode 100644 index 0000000000000..a9abbdbcc3d20 --- /dev/null +++ b/tests/phpunit/data/blocks/notice/shared-script.js @@ -0,0 +1 @@ +/* Another test JavaScript file. */ diff --git a/tests/phpunit/tests/blocks/register.php b/tests/phpunit/tests/blocks/register.php index 3e55206037e40..3c583187d01c8 100644 --- a/tests/phpunit/tests/blocks/register.php +++ b/tests/phpunit/tests/blocks/register.php @@ -52,11 +52,18 @@ public function render_stub() {} * @since 5.0.0 */ public function tear_down() { - $registry = WP_Block_Type_Registry::get_instance(); + // Removes test block types registered by test cases. + $block_types = WP_Block_Type_Registry::get_instance()->get_all_registered(); + foreach ( $block_types as $block_type ) { + $block_name = $block_type->name; + if ( str_starts_with( $block_name, 'tests/' ) ) { + unregister_block_type( $block_name ); + } + } - foreach ( array( 'core/test-static', 'core/test-dynamic', 'tests/notice' ) as $block_name ) { - if ( $registry->is_registered( $block_name ) ) { - $registry->unregister( $block_name ); + foreach ( wp_scripts()->registered as $script_handle ) { + if ( str_starts_with( $script_handle, 'tests-' ) ) { + wp_deregister_script( $script_handle ); } } @@ -134,26 +141,26 @@ public function test_removes_block_asset_path_prefix_and_current_directory() { * @ticket 50263 */ public function test_generate_block_asset_handle() { - $block_name = 'unit-tests/my-block'; + $block_name = 'tests/my-block'; $this->assertSame( - 'unit-tests-my-block-editor-script', + 'tests-my-block-editor-script', generate_block_asset_handle( $block_name, 'editorScript' ) ); $this->assertSame( - 'unit-tests-my-block-script', + 'tests-my-block-script', generate_block_asset_handle( $block_name, 'script', 0 ) ); $this->assertSame( - 'unit-tests-my-block-view-script-100', + 'tests-my-block-view-script-100', generate_block_asset_handle( $block_name, 'viewScript', 99 ) ); $this->assertSame( - 'unit-tests-my-block-editor-style-2', + 'tests-my-block-editor-style-2', generate_block_asset_handle( $block_name, 'editorStyle', 1 ) ); $this->assertSame( - 'unit-tests-my-block-style', + 'tests-my-block-style', generate_block_asset_handle( $block_name, 'style' ) ); } @@ -226,7 +233,7 @@ public function test_wrong_array_index_do_not_register_block_script_handle() { public function test_missing_asset_file_register_block_script_handle() { $metadata = array( 'file' => __FILE__, - 'name' => 'unit-tests/test-block', + 'name' => 'tests/sample-block', 'script' => 'file:./blocks/notice/missing-asset.js', ); $result = register_block_script_handle( $metadata, 'script' ); @@ -264,14 +271,14 @@ public function test_handles_passed_register_block_script_handles() { public function test_success_register_block_script_handle() { $metadata = array( 'file' => DIR_TESTDATA . '/blocks/notice/block.json', - 'name' => 'unit-tests/test-block', + 'name' => 'tests/sample-block', 'script' => 'file:./block.js', ); $result = register_block_script_handle( $metadata, 'script' ); - $this->assertSame( 'unit-tests-test-block-script', $result ); + $this->assertSame( 'tests-sample-block-script', $result ); - // Test the behavior directly within the unit test + // Test the behavior directly within the unit test. $this->assertFalse( strpos( wp_normalize_path( realpath( dirname( $metadata['file'] ) . '/' . $metadata['script'] ) ), @@ -287,6 +294,51 @@ public function test_success_register_block_script_handle() { ); } + /** + * @ticket TBD... + */ + public function test_success_register_block_script_handle_with_custom_handle_name() { + $custom_script_handle = 'tests-my-shared-script'; + $metadata = array( + 'file' => DIR_TESTDATA . '/blocks/notice/block.json', + 'name' => 'tests/sample-block', + 'script' => 'file:./shared-script.js', + ); + $result = register_block_script_handle( $metadata, 'script' ); + + $this->assertSame( $custom_script_handle, $result ); + $this->assertStringEndsWith( + 'shared-script.js', + wp_scripts()->registered[ $custom_script_handle ]->src + ); + } + + /** + * @ticket TBD... + */ + public function test_reuse_registered_block_script_handle_with_custom_handle_name() { + $custom_script_handle = 'tests-my-shared-script'; + $custom_script_src = 'https://example.com/foo.js'; + wp_register_script( $custom_script_handle, $custom_script_src ); + + $this->assertTrue( + wp_script_is( $custom_script_handle, 'registered' ) + ); + + $metadata = array( + 'file' => DIR_TESTDATA . '/blocks/notice/block.json', + 'name' => 'tests/sample-block', + 'script' => 'file:./shared-script.js', + ); + $result = register_block_script_handle( $metadata, 'script' ); + + $this->assertSame( $custom_script_handle, $result ); + $this->assertSame( + $custom_script_src, + wp_scripts()->registered[ $custom_script_handle ]->src + ); + } + /** * @ticket 55513 */ @@ -440,21 +492,21 @@ public function test_handles_passed_register_block_style_handles() { public function test_success_register_block_style_handle() { $metadata = array( 'file' => DIR_TESTDATA . '/blocks/notice/block.json', - 'name' => 'unit-tests/test-block', + 'name' => 'tests/sample-block', 'style' => 'file:./block.css', ); $result = register_block_style_handle( $metadata, 'style' ); - $this->assertSame( 'unit-tests-test-block-style', $result ); - $this->assertFalse( wp_styles()->get_data( 'unit-tests-test-block-style', 'rtl' ) ); + $this->assertSame( 'tests-sample-block-style', $result ); + $this->assertFalse( wp_styles()->get_data( 'tests-sample-block-style', 'rtl' ) ); - // @ticket 50328 + // @ticket 50328. $this->assertSame( wp_normalize_path( realpath( DIR_TESTDATA . '/blocks/notice/block.css' ) ), - wp_normalize_path( wp_styles()->get_data( 'unit-tests-test-block-style', 'path' ) ) + wp_normalize_path( wp_styles()->get_data( 'tests-sample-block-style', 'path' ) ) ); - // Test the behavior directly within the unit test + // Test the behavior directly within the unit test. $this->assertFalse( strpos( wp_normalize_path( realpath( dirname( $metadata['file'] ) . '/' . $metadata['style'] ) ), @@ -483,7 +535,7 @@ public function test_register_block_style_handle_should_load_rtl_stylesheets_for $metadata = array( 'file' => DIR_TESTDATA . '/blocks/notice/block.json', - 'name' => 'unit-tests/test-block-rtl', + 'name' => 'tests/sample-block-rtl', 'style' => 'file:./block.css', ); @@ -491,14 +543,14 @@ public function test_register_block_style_handle_should_load_rtl_stylesheets_for $wp_locale->text_direction = 'rtl'; $handle = register_block_style_handle( $metadata, 'style' ); - $extra_rtl = wp_styles()->get_data( 'unit-tests-test-block-rtl-style', 'rtl' ); - $extra_suffix = wp_styles()->get_data( 'unit-tests-test-block-rtl-style', 'suffix' ); - $extra_path = wp_normalize_path( wp_styles()->get_data( 'unit-tests-test-block-rtl-style', 'path' ) ); + $extra_rtl = wp_styles()->get_data( 'tests-sample-block-rtl-style', 'rtl' ); + $extra_suffix = wp_styles()->get_data( 'tests-sample-block-rtl-style', 'suffix' ); + $extra_path = wp_normalize_path( wp_styles()->get_data( 'tests-sample-block-rtl-style', 'path' ) ); $wp_locale->text_direction = $orig_text_dir; $this->assertSame( - 'unit-tests-test-block-rtl-style', + 'tests-sample-block-rtl-style', $handle, 'The handle did not match the expected handle.' ); @@ -528,13 +580,13 @@ public function test_register_block_style_handle_should_load_rtl_stylesheets_for public function test_register_nonexistent_stylesheet() { $metadata = array( 'file' => DIR_TESTDATA . '/blocks/notice/block.json', - 'name' => 'unit-tests/test-block-nonexistent-stylesheet', + 'name' => 'tests/sample-block-nonexistent-stylesheet', 'style' => 'file:./nonexistent.css', ); register_block_style_handle( $metadata, 'style' ); global $wp_styles; - $this->assertFalse( $wp_styles->registered['unit-tests-test-block-nonexistent-stylesheet-style']->src ); + $this->assertFalse( $wp_styles->registered['tests-sample-block-nonexistent-stylesheet-style']->src ); } /** @@ -638,13 +690,13 @@ public function test_block_registers_with_metadata_fixture() { $result->provides_context ); $this->assertSameSets( array( 'groupId' ), $result->uses_context ); - // @ticket 57585 + // @ticket 57585. $this->assertSame( array( 'root' => '.wp-block-notice' ), $result->selectors, 'Block type should contain selectors from metadata.' ); - // @ticket 59346 + // @ticket 59346. $this->assertSameSets( array( 'tests/before' => 'before', @@ -716,13 +768,13 @@ public function test_block_registers_with_metadata_fixture() { $result->style_handles ); - // @ticket 50328 + // @ticket 50328. $this->assertSame( wp_normalize_path( realpath( DIR_TESTDATA . '/blocks/notice/block.css' ) ), - wp_normalize_path( wp_styles()->get_data( 'unit-tests-test-block-style', 'path' ) ) + wp_normalize_path( wp_styles()->get_data( 'tests-sample-block-style', 'path' ) ) ); - // @ticket 53148 + // @ticket 53148. $this->assertIsCallable( $result->render_callback ); }