From f57725f66724eceb3ec5e5f356949296ea85741d Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 30 May 2024 16:31:59 +0200 Subject: [PATCH] Use script_module_data filter for Interactivity data Use the "script_module_data_@wordpress/interactivity" filter to pass Script Module data to the Interactivity API client. --- .../class-wp-interactivity-api.php | 75 ++++++------------- 1 file changed, 24 insertions(+), 51 deletions(-) diff --git a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php index 3924e877638a7..50fb4d6ac216f 100644 --- a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php +++ b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php @@ -192,14 +192,29 @@ public function config( string $store_namespace, array $config = array() ): arra * configuration will be available using a `getConfig` utility. * * @since 6.5.0 + * + * @deprecated 6.7.0 Client data passing is handled by the {@see "script_module_data_{$module_id}"} filter. */ public function print_client_interactivity_data() { + _deprecated_function( __METHOD__, '6.7.0' ); + } + + /** + * Set client-side interactivity data. + * + * Once in the browser, the state will be parsed and used to hydrate the client-side + * interactivity stores and the configuration will be available using a `getConfig` utility. + * + * @since 6.7.0 + * + * @param array $data Data to filter. + * @return array Data for the Interactivity API script module. + */ + public function filter_script_module_interactivity_data( array $data ): array { if ( empty( $this->state_data ) && empty( $this->config_data ) ) { - return; + return $data; } - $interactivity_data = array(); - $config = array(); foreach ( $this->config_data as $key => $value ) { if ( ! empty( $value ) ) { @@ -207,7 +222,7 @@ public function print_client_interactivity_data() { } } if ( ! empty( $config ) ) { - $interactivity_data['config'] = $config; + $data['config'] = $config; } $state = array(); @@ -217,52 +232,10 @@ public function print_client_interactivity_data() { } } if ( ! empty( $state ) ) { - $interactivity_data['state'] = $state; + $data['state'] = $state; } - if ( ! empty( $interactivity_data ) ) { - /* - * This data will be printed as JSON inside a script tag like this: - * - * - * A script tag must be closed by a sequence beginning with `` will be printed as `\u003C/script\u00E3`. - * - * - JSON_HEX_TAG: All < and > are converted to \u003C and \u003E. - * - JSON_UNESCAPED_SLASHES: Don't escape /. - * - * If the page will use UTF-8 encoding, it's safe to print unescaped unicode: - * - * - JSON_UNESCAPED_UNICODE: Encode multibyte Unicode characters literally (instead of as `\uXXXX`). - * - JSON_UNESCAPED_LINE_TERMINATORS: The line terminators are kept unescaped when - * JSON_UNESCAPED_UNICODE is supplied. It uses the same behaviour as it was - * before PHP 7.1 without this constant. Available as of PHP 7.1.0. - * - * The JSON specification requires encoding in UTF-8, so if the generated HTML page - * is not encoded in UTF-8 then it's not safe to include those literals. They must - * be escaped to avoid encoding issues. - * - * @see https://www.rfc-editor.org/rfc/rfc8259.html for details on encoding requirements. - * @see https://www.php.net/manual/en/json.constants.php for details on these constants. - * @see https://html.spec.whatwg.org/#script-data-state for details on script tag parsing. - */ - $json_encode_flags = JSON_HEX_TAG | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS; - if ( ! is_utf8_charset() ) { - $json_encode_flags = JSON_HEX_TAG | JSON_UNESCAPED_SLASHES; - } - - wp_print_inline_script_tag( - wp_json_encode( - $interactivity_data, - $json_encode_flags - ), - array( - 'type' => 'application/json', - 'id' => 'wp-interactivity-data', - ) - ); - } + return $data; } /** @@ -329,13 +302,13 @@ public function register_script_modules() { * Adds the necessary hooks for the Interactivity API. * * @since 6.5.0 + * @since 6.7.0 Use the {@see "script_module_data_{$module_id}"} filter to pass client-side data. */ public function add_hooks() { add_action( 'wp_enqueue_scripts', array( $this, 'register_script_modules' ) ); - add_action( 'wp_footer', array( $this, 'print_client_interactivity_data' ) ); - add_action( 'admin_enqueue_scripts', array( $this, 'register_script_modules' ) ); - add_action( 'admin_print_footer_scripts', array( $this, 'print_client_interactivity_data' ) ); + + add_filter( 'script_module_data_@wordpress/interactivity', array( $this, 'filter_script_module_interactivity_data' ) ); } /**