Blocks: Allow reading the script handle from asset files

In the [documentation for WPDefinedAsset definition](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#wpdefinedasset) for block metadata there is a note about the handle. That was missing in WordPress core.

Props gziolo, jsnajdr, youknowriad.
Fixes #60485.




git-svn-id: https://develop.svn.wordpress.org/trunk@57590 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Greg Ziółkowski
2024-02-12 11:40:49 +00:00
parent 68edf43fa9
commit 0422b53ad2
4 changed files with 130 additions and 69 deletions

View File

@@ -191,7 +191,7 @@ function register_block_script_module_id( $metadata, $field_name, $index = 0 ) {
*
* @since 5.5.0
* @since 6.1.0 Added `$index` parameter.
* @since 6.5.0 The asset file is optional.
* @since 6.5.0 The asset file is optional. Added script handle support in the asset file.
*
* @param array $metadata Block metadata.
* @param string $field_name Field name to pick from metadata.
@@ -205,42 +205,49 @@ 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 )
);
$script_path_norm = wp_normalize_path( realpath( $path . '/' . $script_path ) );
$script_uri = get_block_asset_url( $script_path_norm );
// Asset file for blocks is optional. See https://core.trac.wordpress.org/ticket/60460.
$script_asset = ! empty( $script_asset_path ) ? require $script_asset_path : array();
$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_args = array();
$script_path_norm = wp_normalize_path( realpath( $path . '/' . $script_path ) );
$script_uri = get_block_asset_url( $script_path_norm );
$script_dependencies = isset( $script_asset['dependencies'] ) ? $script_asset['dependencies'] : array();
$block_version = isset( $metadata['version'] ) ? $metadata['version'] : false;
$script_version = isset( $script_asset['version'] ) ? $script_asset['version'] : $block_version;
$script_args = array();
if ( 'viewScript' === $field_name && $script_uri ) {
$script_args['strategy'] = 'defer';
}
// Asset file for blocks is optional. See https://core.trac.wordpress.org/ticket/60460.
$script_asset = ! empty( $script_asset_path ) ? require $script_asset_path : array();
$script_dependencies = isset( $script_asset['dependencies'] ) ? $script_asset['dependencies'] : array();
$result = wp_register_script(
$result = wp_register_script(
$script_handle,
$script_uri,
$script_dependencies,
isset( $script_asset['version'] ) ? $script_asset['version'] : false,
$script_version,
$script_args
);
if ( ! $result ) {

View File

@@ -0,0 +1,7 @@
<?php
return array(
'handle' => 'tests-my-shared-script',
'dependencies' => array(),
'version' => 'test',
);

View File

@@ -0,0 +1 @@
/* Another test JavaScript file. */

View File

@@ -52,16 +52,17 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
* @since 5.0.0
*/
public function tear_down() {
$registry = WP_Block_Type_Registry::get_instance();
foreach ( array( 'core/test-static', 'core/test-dynamic', 'tests/notice' ) as $block_name ) {
if ( $registry->is_registered( $block_name ) ) {
$registry->unregister( $block_name );
// 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 ( wp_scripts()->registered as $script_handle => $script ) {
if ( str_starts_with( $script_handle, 'unit-tests-' ) ) {
if ( str_starts_with( $script_handle, 'tests-' ) ) {
wp_deregister_script( $script_handle );
}
}
@@ -82,7 +83,7 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
* @ticket 45109
*/
public function test_register_affects_main_registry() {
$name = 'core/test-static';
$name = 'tests/static';
$settings = array(
'icon' => 'text',
);
@@ -97,7 +98,7 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
* @ticket 45109
*/
public function test_unregister_affects_main_registry() {
$name = 'core/test-static';
$name = 'tests/static';
$settings = array(
'icon' => 'text',
);
@@ -141,43 +142,43 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
* @ticket 60233
*/
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-view-script-module',
'tests-my-block-view-script-module',
generate_block_asset_handle( $block_name, 'viewScriptModule' )
);
$this->assertSame(
'unit-tests-my-block-view-script-module-2',
'tests-my-block-view-script-module-2',
generate_block_asset_handle( $block_name, 'viewScriptModule', 1 )
);
$this->assertSame(
'unit-tests-my-block-view-script-module-100',
'tests-my-block-view-script-module-100',
generate_block_asset_handle( $block_name, 'viewScriptModule', 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' )
);
// @ticket 59673
$this->assertSame(
'unit-tests-my-block-view-style',
'tests-my-block-view-style',
generate_block_asset_handle( $block_name, 'viewStyle' ),
'asset handle for viewStyle is not generated correctly'
);
@@ -335,12 +336,12 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
public function test_missing_asset_file_register_block_script_module_id() {
$metadata = array(
'file' => __FILE__,
'name' => 'unit-tests/test-block',
'name' => 'tests/test-block',
'viewScriptModule' => 'file:./blocks/notice/missing-asset.js',
);
$result = register_block_script_module_id( $metadata, 'viewScriptModule' );
$this->assertSame( 'unit-tests-test-block-view-script-module', $result );
$this->assertSame( 'tests-test-block-view-script-module', $result );
}
/**
@@ -376,14 +377,14 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
public function test_success_register_block_script_module_id() {
$metadata = array(
'file' => DIR_TESTDATA . '/blocks/notice/block.json',
'name' => 'unit-tests/test-block',
'name' => 'tests/test-block',
'viewScriptModule' => 'file:./block.js',
);
$result = register_block_script_module_id( $metadata, 'viewScriptModule' );
$this->assertSame( 'unit-tests-test-block-view-script-module', $result );
$this->assertSame( 'tests-test-block-view-script-module', $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['viewScriptModule'] ) ),
@@ -430,12 +431,12 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
public function test_missing_asset_file_register_block_script_handle_with_default_settings() {
$metadata = array(
'file' => __FILE__,
'name' => 'unit-tests/test-block',
'name' => 'tests/test-block',
'script' => 'file:./blocks/notice/missing-asset.js',
);
$result = register_block_script_handle( $metadata, 'script' );
$this->assertSame( 'unit-tests-test-block-script', $result );
$this->assertSame( 'tests-test-block-script', $result );
}
/**
@@ -444,14 +445,14 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
public function test_success_register_block_script_handle() {
$metadata = array(
'file' => DIR_TESTDATA . '/blocks/notice/block.json',
'name' => 'unit-tests/test-block',
'name' => 'tests/test-block',
'script' => 'file:./block.js',
);
$result = register_block_script_handle( $metadata, 'script' );
$this->assertSame( 'unit-tests-test-block-script', $result );
$this->assertSame( 'tests-test-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'] ) ),
@@ -467,6 +468,51 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
);
}
/**
* @ticket 60485
*/
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 60485
*/
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
*/
@@ -620,33 +666,33 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
public function test_success_register_block_style_handle() {
$metadata = array(
'file' => DIR_TESTDATA . '/blocks/notice/block.json',
'name' => 'unit-tests/test-block',
'name' => 'tests/test-block',
'style' => 'file:./block.css',
'viewStyle' => 'file:./block-view.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-test-block-style', $result );
$this->assertFalse( wp_styles()->get_data( 'tests-test-block-style', 'rtl' ) );
// @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-test-block-style', 'path' ) )
);
// Test viewStyle property
$result = register_block_style_handle( $metadata, 'viewStyle' );
$this->assertSame( 'unit-tests-test-block-view-style', $result );
$this->assertSame( 'tests-test-block-view-style', $result );
// @ticket 59673
$this->assertSame(
wp_normalize_path( realpath( DIR_TESTDATA . '/blocks/notice/block-view.css' ) ),
wp_normalize_path( wp_styles()->get_data( 'unit-tests-test-block-view-style', 'path' ) ),
wp_normalize_path( wp_styles()->get_data( 'tests-test-block-view-style', 'path' ) ),
'viewStyle asset path is not correct'
);
// 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'] ) ),
@@ -675,7 +721,7 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
$metadata = array(
'file' => DIR_TESTDATA . '/blocks/notice/block.json',
'name' => 'unit-tests/test-block-rtl',
'name' => 'tests/test-block-rtl',
'style' => 'file:./block.css',
);
@@ -683,14 +729,14 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
$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-test-block-rtl-style', 'rtl' );
$extra_suffix = wp_styles()->get_data( 'tests-test-block-rtl-style', 'suffix' );
$extra_path = wp_normalize_path( wp_styles()->get_data( 'tests-test-block-rtl-style', 'path' ) );
$wp_locale->text_direction = $orig_text_dir;
$this->assertSame(
'unit-tests-test-block-rtl-style',
'tests-test-block-rtl-style',
$handle,
'The handle did not match the expected handle.'
);
@@ -720,13 +766,13 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
public function test_register_nonexistent_stylesheet() {
$metadata = array(
'file' => DIR_TESTDATA . '/blocks/notice/block.json',
'name' => 'unit-tests/test-block-nonexistent-stylesheet',
'name' => 'tests/test-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-test-block-nonexistent-stylesheet-style']->src );
}
/**
@@ -1044,13 +1090,13 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
// @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-test-block-style', 'path' ) )
);
// @ticket 59673
$this->assertSame(
wp_normalize_path( realpath( DIR_TESTDATA . '/blocks/notice/block-view.css' ) ),
wp_normalize_path( wp_styles()->get_data( 'unit-tests-test-block-view-style', 'path' ) ),
wp_normalize_path( wp_styles()->get_data( 'tests-test-block-view-style', 'path' ) ),
'viewStyle asset path is not correct'
);
@@ -1089,10 +1135,10 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
*/
public function test_register_block_type_accepts_editor_script_array( $editor_script, $expected ) {
$settings = array( 'editor_script' => $editor_script );
register_block_type( 'core/test-static', $settings );
register_block_type( 'tests/static', $settings );
$registry = WP_Block_Type_Registry::get_instance();
$block_type = $registry->get_registered( 'core/test-static' );
$block_type = $registry->get_registered( 'tests/static' );
$this->assertObjectHasProperty( 'editor_script_handles', $block_type );
$actual_script = $block_type->editor_script;
$actual_script_handles = $block_type->editor_script_handles;
@@ -1155,10 +1201,10 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
*/
public function test_register_block_type_throws_doing_it_wrong( $editor_script, $expected ) {
$settings = array( 'editor_script' => $editor_script );
register_block_type( 'core/test-static', $settings );
register_block_type( 'tests/static', $settings );
$registry = WP_Block_Type_Registry::get_instance();
$block_type = $registry->get_registered( 'core/test-static' );
$block_type = $registry->get_registered( 'tests/static' );
$this->assertObjectHasProperty( 'editor_script_handles', $block_type );
$actual_script = $block_type->editor_script;
$actual_script_handles = $block_type->editor_script_handles;
@@ -1248,13 +1294,13 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
* @ticket 45109
*/
public function test_get_dynamic_block_names() {
register_block_type( 'core/test-static', array() );
register_block_type( 'core/test-dynamic', array( 'render_callback' => array( $this, 'render_stub' ) ) );
register_block_type( 'tests/static', array() );
register_block_type( 'tests/dynamic', array( 'render_callback' => array( $this, 'render_stub' ) ) );
$dynamic_block_names = get_dynamic_block_names();
$this->assertContains( 'core/test-dynamic', $dynamic_block_names );
$this->assertNotContains( 'core/test-static', $dynamic_block_names );
$this->assertContains( 'tests/dynamic', $dynamic_block_names );
$this->assertNotContains( 'tests/static', $dynamic_block_names );
}
/**