summaryrefslogtreecommitdiffstats
path: root/wp-includes/interactivity-api/interactivity-api.php
diff options
context:
space:
mode:
Diffstat (limited to 'wp-includes/interactivity-api/interactivity-api.php')
-rw-r--r--wp-includes/interactivity-api/interactivity-api.php170
1 files changed, 170 insertions, 0 deletions
diff --git a/wp-includes/interactivity-api/interactivity-api.php b/wp-includes/interactivity-api/interactivity-api.php
new file mode 100644
index 0000000..b8f3e50
--- /dev/null
+++ b/wp-includes/interactivity-api/interactivity-api.php
@@ -0,0 +1,170 @@
+<?php
+/**
+ * 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;
+}
+/*
+ * Uses a priority of 100 to ensure that other filters can add additional attributes to
+ * $parsed_block before the processing starts.
+ */
+add_filter( 'render_block_data', 'wp_interactivity_process_directives_of_interactive_blocks', 100, 1 );
+
+/**
+ * Retrieves the main WP_Interactivity_API instance.
+ *
+ * It provides access to the WP_Interactivity_API instance, creating one if it
+ * doesn't exist yet.
+ *
+ * @since 6.5.0
+ *
+ * @global WP_Interactivity_API $wp_interactivity
+ *
+ * @return WP_Interactivity_API The main WP_Interactivity_API instance.
+ */
+function wp_interactivity(): WP_Interactivity_API {
+ global $wp_interactivity;
+ if ( ! ( $wp_interactivity instanceof WP_Interactivity_API ) ) {
+ $wp_interactivity = new WP_Interactivity_API();
+ }
+ return $wp_interactivity;
+}
+
+/**
+ * Processes the interactivity directives contained within the HTML content
+ * and updates the markup accordingly.
+ *
+ * @since 6.5.0
+ *
+ * @param string $html The HTML content to process.
+ * @return string The processed HTML content. It returns the original content when the HTML contains unbalanced tags.
+ */
+function wp_interactivity_process_directives( string $html ): string {
+ return wp_interactivity()->process_directives( $html );
+}
+
+/**
+ * Gets and/or sets the initial state of an Interactivity API store for a
+ * given namespace.
+ *
+ * If state for that store namespace already exists, it merges the new
+ * provided state with the existing one.
+ *
+ * @since 6.5.0
+ *
+ * @param string $store_namespace The unique store namespace identifier.
+ * @param array $state Optional. The array that will be merged with the existing state for the specified
+ * store namespace.
+ * @return array The state for the specified store namespace. This will be the updated state if a $state argument was
+ * provided.
+ */
+function wp_interactivity_state( string $store_namespace, array $state = array() ): array {
+ return wp_interactivity()->state( $store_namespace, $state );
+}
+
+/**
+ * Gets and/or sets the configuration of the Interactivity API for a given
+ * store namespace.
+ *
+ * If configuration for that store namespace exists, it merges the new
+ * provided configuration with the existing one.
+ *
+ * @since 6.5.0
+ *
+ * @param string $store_namespace The unique store namespace identifier.
+ * @param array $config Optional. The array that will be merged with the existing configuration for the
+ * specified store namespace.
+ * @return array The configuration for the specified store namespace. This will be the updated configuration if a
+ * $config argument was provided.
+ */
+function wp_interactivity_config( string $store_namespace, array $config = array() ): array {
+ return wp_interactivity()->config( $store_namespace, $config );
+}
+
+/**
+ * Generates a `data-wp-context` directive attribute by encoding a context
+ * array.
+ *
+ * This helper function simplifies the creation of `data-wp-context` directives
+ * by providing a way to pass an array of data, which encodes into a JSON string
+ * safe for direct use as a HTML attribute value.
+ *
+ * Example:
+ *
+ * <div <?php echo wp_interactivity_data_wp_context( array( 'isOpen' => true, 'count' => 0 ) ); ?>>
+ *
+ * @since 6.5.0
+ *
+ * @param array $context The array of context data to encode.
+ * @param string $store_namespace Optional. The unique store namespace identifier.
+ * @return string A complete `data-wp-context` directive with a JSON encoded value representing the context array and
+ * the store namespace if specified.
+ */
+function wp_interactivity_data_wp_context( array $context, string $store_namespace = '' ): string {
+ return 'data-wp-context=\'' .
+ ( $store_namespace ? $store_namespace . '::' : '' ) .
+ ( empty( $context ) ? '{}' : wp_json_encode( $context, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP ) ) .
+ '\'';
+}