WordPress Version: 6.5
/**
* Interactivity API: Functions and hooks
*
* @package WordPress
* @subpackage Interactivity API
* @since 6.5.0
*/
/**
* Processes the directives on the rendered HTML of the interactive blocks.
*
* This processes only one root interactive block at a time because the
* rendered HTML of that block contains the rendered HTML of all its inner
* blocks, including any interactive block. It does so by ignoring all the
* interactive inner blocks until the root interactive block is processed.
*
* @since 6.5.0
*
* @param array $parsed_block The parsed block.
* @return array The same parsed block.
*/
function wp_interactivity_process_directives_of_interactive_blocks(array $parsed_block): array
{
static $root_interactive_block = null;
/*
* Checks whether a root interactive block is already annotated for
* processing, and if it is, it ignores the subsequent ones.
*/
if (null === $root_interactive_block) {
$block_name = $parsed_block['blockName'];
$block_type = WP_Block_Type_Registry::get_instance()->get_registered($block_name);
if (isset($block_name) && (isset($block_type->supports['interactivity']) && true === $block_type->supports['interactivity'] || isset($block_type->supports['interactivity']['interactive']) && true === $block_type->supports['interactivity']['interactive'])) {
// Annotates the root interactive block for processing.
$root_interactive_block = array($block_name, $parsed_block);
/*
* Adds a filter to process the root interactive block once it has
* finished rendering.
*/
$process_interactive_blocks = static function (string $content, array $parsed_block) use (&$root_interactive_block, &$process_interactive_blocks): string {
// Checks whether the current block is the root interactive block.
list($root_block_name, $root_parsed_block) = $root_interactive_block;
if ($root_block_name === $parsed_block['blockName'] && $parsed_block === $root_parsed_block) {
// The root interactive blocks has finished rendering, process it.
$content = wp_interactivity_process_directives($content);
// Removes the filter and reset the root interactive block.
remove_filter('render_block_' . $parsed_block['blockName'], $process_interactive_blocks);
$root_interactive_block = null;
}
return $content;
};
/*
* Uses a priority of 100 to ensure that other filters can add additional
* directives before the processing starts.
*/
add_filter('render_block_' . $block_name, $process_interactive_blocks, 100, 2);
}
}
return $parsed_block;
}