diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index 62d6a269c844f..8c22c7d7d6cea 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -1146,6 +1146,112 @@ function build_query_vars_from_query_block( $block, $page ) { return $query; } +/** + * Enqueue a stylesheet for a specific block. + * + * If the theme has opted-in to separate-styles loading, + * then the stylesheet will be enqueued on-render, + * otherwise when the block inits. + * + * @param string $block_name The block-name, including namespace. + * @param array $args An array of arguments [handle,src,deps,ver,media]. + * + * @return void + */ +function wp_enqueue_block_style( $block_name, $args ) { + $args = wp_parse_args( + $args, + array( + 'handle' => '', + 'src' => '', + 'deps' => array(), + 'ver' => false, + 'media' => 'all', + ) + ); + + /** + * Callback function to register and enqueue styles. + * + * @param string $content When the callback is used for the render_block filter, + * the content needs to be returned so the function parameter + * is to ensure the content exists. + * + * @return string + */ + $callback = function( $content ) use ( $args ) { + // Register the stylesheet. + if ( ! empty( $args['src'] ) ) { + wp_register_style( $args['handle'], $args['src'], $args['deps'], $args['ver'], $args['media'] ); + } + + // Add `path` data if provided. + if ( isset( $args['path'] ) ) { + wp_style_add_data( $args['handle'], 'path', $args['path'] ); + + // Get the RTL file path. + $rtl_file_path = str_replace( '.css', '-rtl.css', $args['path'] ); + + // Add RTL stylesheet. + if ( file_exists( $rtl_file_path ) ) { + wp_style_add_data( $args['hanle'], 'rtl', 'replace' ); + + if ( is_rtl() ) { + wp_style_add_data( $args['handle'], 'path', $rtl_file_path ); + } + } + } + + // Enqueue the stylesheet. + wp_enqueue_style( $args['handle'] ); + + return $content; + }; + + $hook = did_action( 'wp_enqueue_scripts' ) ? 'wp_footer' : 'wp_enqueue_scripts'; + if ( wp_should_load_separate_core_block_assets() ) { + $hook = "render_block_$block_name"; + } + + // Enqueue assets in the frontend. + add_filter( $hook, $callback ); + + // Enqueue assets in the editor. + add_action( 'enqueue_block_assets', $callback ); +} + +/** + * Allow multiple block styles. + * + * @param array $metadata Metadata for registering a block type. + * + * @return array + */ +function _wp_multiple_block_styles( $metadata ) { + foreach ( array( 'style', 'editorStyle' ) as $key ) { + if ( ! empty( $metadata[ $key ] ) && is_array( $metadata[ $key ] ) ) { + $default_style = array_shift( $metadata[ $key ] ); + foreach ( $metadata[ $key ] as $handle ) { + $args = array( 'handle' => $handle ); + if ( 0 === strpos( $handle, 'file:' ) && isset( $metadata['file'] ) ) { + $style_path = remove_block_asset_path_prefix( $handle ); + $args = array( + 'handle' => sanitize_key( "{$metadata['name']}-{$style_path}" ), + 'src' => plugins_url( $style_path, $metadata['file'] ), + ); + } + + wp_enqueue_block_style( $metadata['name'], $args ); + } + + // Only return the 1st item in the array. + $metadata[ $key ] = $default_style; + } + } + return $metadata; +} +add_filter( 'block_type_metadata', '_wp_multiple_block_styles' ); + // TODO: Stub, remove this. function get_allowed_block_template_part_areas() { return array();