Skip to content

Commit

Permalink
Add pre 6.5 compat for viewStyles (WordPress#59322)
Browse files Browse the repository at this point in the history
* Add pre 6.5 compat for viewStyles

* docblock feedback

Unlinked contributors: chimok.

Co-authored-by: gaambo <[email protected]>
Co-authored-by: gziolo <[email protected]>
  • Loading branch information
3 people authored and carstingaxion committed Mar 27, 2024
1 parent 21c8e1a commit 3896b50
Showing 1 changed file with 201 additions and 7 deletions.
208 changes: 201 additions & 7 deletions lib/compat/wordpress-6.5/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,13 @@ function gutenberg_block_bindings_replace_html( $block_content, $block_name, str
return;
}

/**
* Process the block bindings attribute.
*
* @param string $block_content Block Content.
* @param array $parsed_block The full block, including name and attributes.
* @param WP_Block $block_instance The block instance.
*/
/**
* Process the block bindings attribute.
*
* @param string $block_content Block Content.
* @param array $parsed_block The full block, including name and attributes.
* @param WP_Block $block_instance The block instance.
*/
function gutenberg_process_block_bindings( $block_content, $parsed_block, $block_instance ) {
$supported_block_attrs = array(
'core/paragraph' => array( 'content' ),
Expand Down Expand Up @@ -217,3 +217,197 @@ function gutenberg_process_block_bindings( $block_content, $parsed_block, $block
}

add_filter( 'render_block', 'gutenberg_process_block_bindings', 20, 3 );

/**
* Enable the viewStyle block API for core versions < 6.5
*
*/
if ( ! property_exists( 'WP_Block_Type', 'view_style_handles' ) ) {
/**
* Registers viewStyle assets on block type registration (=same moment core would do it).
*
* @param array $settings Array of determined settings for registering a block type.
* @param array $metadata Metadata provided for registering a block type.
* @return array The block type settings
*/
function gutenberg_filter_block_type_metadata_settings_register_view_styles( $settings, $metadata ) {
if ( empty( $metadata['viewStyle'] ) ) {
return $settings;
}
$styles = $metadata['viewStyle'];
$processed_styles = array();
if ( is_array( $styles ) ) {
for ( $index = 0; $index < count( $styles ); $index++ ) {
$result = gutenberg_register_block_view_style_handle(
$metadata,
$index
);
if ( $result ) {
$processed_styles[] = $result;
}
}
} else {
$result = gutenberg_register_block_view_style_handle(
$metadata
);
if ( $result ) {
$processed_styles[] = $result;
}
}

if ( ! empty( $processed_styles ) ) {
$settings['view_style_handles'] = $processed_styles;
}
return $settings;
}

add_filter( 'block_type_metadata_settings', 'gutenberg_filter_block_type_metadata_settings_register_view_styles', 10, 2 );

/**
* Enqueue view styles associated with the block.
*
* @param string $block_content The block content.
* @param array $block The full block, including name and attributes.
* @param WP_Block $instance The block instance.
*/
function gutenberg_filter_render_block_enqueue_view_styles( $block_content, $parsed_block, $block_instance ) {
$block_type = $block_instance->block_type;

if ( ! empty( $block_type->view_style_handles ) ) {
foreach ( $block_type->view_style_handles as $view_style_handle ) {
wp_enqueue_style( $view_style_handle );
}
}

return $block_content;
}

add_filter( 'render_block', 'gutenberg_filter_render_block_enqueue_view_styles', 10, 3 );


/**
* Registers a REST field for block types to provide view styles.
*
* Adds the `view_style_handles` field to block type objects in the REST API, which
* lists the style handles associated with the block's viewStyle key.
*/
function gutenberg_register_view_style_rest_field() {
register_rest_field(
'block-type',
'view_style_handles',
array(
'get_callback' => function ( $item ) {
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $item['name'] );
if ( isset( $block_type->view_style_handles ) ) {
return $block_type->view_style_handles;
}
return array();
},
)
);
}

add_action( 'rest_api_init', 'gutenberg_register_view_style_rest_field' );

/**
* A compat version of `register_block_style_handle()` to use the viewStyle handle.
* Required for core versions < 6.5, since a custom version of generate_block_asset_handle has to be used
* that supports the viewStyle property and correctly creates the handle
*
* @param array $metadata Block metadata.
* @param int $index Optional. Index of the style to register when multiple items passed.
* Default 0.
* @return string|false Style handle provided directly or created through
* style's registration, or false on failure.
*/
function gutenberg_register_block_view_style_handle( $metadata, $index = 0 ) {
$style_handle = $metadata['viewStyle'];
if ( is_array( $style_handle ) ) {
if ( empty( $style_handle[ $index ] ) ) {
return false;
}
$style_handle = $style_handle[ $index ];
}
$style_handle_name = gutenberg_generate_view_style_block_asset_handle( $metadata['name'], $index );
// If the style handle is already registered, skip re-registering.
if ( wp_style_is( $style_handle_name, 'registered' ) ) {
return $style_handle_name;
}
static $wpinc_path_norm = '';
if ( ! $wpinc_path_norm ) {
$wpinc_path_norm = wp_normalize_path( realpath( ABSPATH . WPINC ) );
}
$is_core_block = isset( $metadata['file'] ) && str_starts_with( $metadata['file'], $wpinc_path_norm );
// Skip registering individual styles for each core block when a bundled version provided.
if ( $is_core_block && ! wp_should_load_separate_core_block_assets() ) {
return false;
}
$style_path = remove_block_asset_path_prefix( $style_handle );
$is_style_handle = $style_handle === $style_path;
// Allow only passing style handles for core blocks.
if ( $is_core_block && ! $is_style_handle ) {
return false;
}
// Return the style handle unless it's the first item for every core block that requires special treatment.
if ( $is_style_handle && ! ( $is_core_block && 0 === $index ) ) {
return $style_handle;
}
// Check whether styles should have a ".min" suffix or not.
$suffix = SCRIPT_DEBUG ? '' : '.min';
if ( $is_core_block ) {
$style_path = "view{$suffix}.css"; // Use view.css for viewStyle of core blocks
}
$style_path_norm = wp_normalize_path( realpath( dirname( $metadata['file'] ) . '/' . $style_path ) );
$style_uri = get_block_asset_url( $style_path_norm );
$version = ! $is_core_block && isset( $metadata['version'] ) ? $metadata['version'] : false;
$result = wp_register_style(
$style_handle_name,
$style_uri,
array(),
$version
);
if ( ! $result ) {
return false;
}
if ( $style_uri ) {
wp_style_add_data( $style_handle_name, 'path', $style_path_norm );
if ( $is_core_block ) {
$rtl_file = str_replace( "{$suffix}.css", "-rtl{$suffix}.css", $style_path_norm );
} else {
$rtl_file = str_replace( '.css', '-rtl.css', $style_path_norm );
}
if ( is_rtl() && file_exists( $rtl_file ) ) {
wp_style_add_data( $style_handle_name, 'rtl', 'replace' );
wp_style_add_data( $style_handle_name, 'suffix', $suffix );
wp_style_add_data( $style_handle_name, 'path', $rtl_file );
}
}
return $style_handle_name;
}

/**
* A compat version of `generate_block_asset_handle()` to use the viewStyle asset handle.
*
* @param string $block_name Name of the block.
* @param string $field_name Name of the metadata field.
* @param int $index Optional. Index of the asset when multiple items passed.
* Default 0.
* @return string Generated asset name for the block's field.
*/
function gutenberg_generate_view_style_block_asset_handle( $block_name, $index = 0 ) {
if ( str_starts_with( $block_name, 'core/' ) ) {
$asset_handle = str_replace( 'core/', 'wp-block-', $block_name );
$asset_handle .= '-view';
if ( $index > 0 ) {
$asset_handle .= '-' . ( $index + 1 );
}
return $asset_handle;
}

$asset_handle = str_replace( '/', '-', $block_name ) . '-view-style';
if ( $index > 0 ) {
$asset_handle .= '-' . ( $index + 1 );
}
return $asset_handle;
}
}

0 comments on commit 3896b50

Please sign in to comment.