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 8a2bc3467566a..e621bc5c2393a 100644 --- a/src/wp-includes/interactivity-api/class-wp-interactivity-api.php +++ b/src/wp-includes/interactivity-api/class-wp-interactivity-api.php @@ -401,9 +401,9 @@ public function register_script_modules() { * @since 6.9.0 Adds support for client-side navigation in script modules. */ public function add_hooks() { - add_filter( 'script_module_data_@wordpress/interactivity', array( $this, 'filter_script_module_interactivity_data' ) ); - add_filter( 'script_module_data_@wordpress/interactivity-router', array( $this, 'filter_script_module_interactivity_router_data' ) ); - add_filter( 'wp_script_attributes', array( $this, 'add_load_on_client_navigation_attribute_to_script_modules' ) ); + add_filter( 'script_module_data_@wordpress/interactivity', 'wp_interactivity_script_module_data' ); + add_filter( 'script_module_data_@wordpress/interactivity-router', 'wp_interactivity_router_script_module_data' ); + add_filter( 'wp_script_attributes', 'wp_interactivity_script_module_attributes' ); } /** @@ -1516,7 +1516,7 @@ private function data_wp_router_region_processor( WP_Interactivity_API_Directive wp_enqueue_style( 'wp-interactivity-router-animations' ); // Adds the necessary markup to the footer. - add_action( 'wp_footer', array( $this, 'print_router_markup' ) ); + add_action( 'wp_footer', 'wp_interactivity_print_router_markup' ); } } diff --git a/src/wp-includes/interactivity-api/interactivity-api.php b/src/wp-includes/interactivity-api/interactivity-api.php index 105f3f6f29c18..7de5d77191e41 100644 --- a/src/wp-includes/interactivity-api/interactivity-api.php +++ b/src/wp-includes/interactivity-api/interactivity-api.php @@ -138,3 +138,56 @@ function wp_interactivity_get_context( ?string $store_namespace = null ): array function wp_interactivity_get_element(): ?array { return wp_interactivity()->get_element(); } + +/** + * Filters the data for the `@wordpress/interactivity` script module. + * + * @since 7.2.0 + * + * @see WP_Interactivity_API::filter_script_module_interactivity_data() + * + * @param array $data Data to filter. + * @return array Data for the Interactivity API script module. + */ +function wp_interactivity_script_module_data( array $data ): array { + return wp_interactivity()->filter_script_module_interactivity_data( $data ); +} + +/** + * Filters the data for the `@wordpress/interactivity-router` script module. + * + * @since 7.2.0 + * + * @see WP_Interactivity_API::filter_script_module_interactivity_router_data() + * + * @param array $data Data to filter. + * @return array Data for the Interactivity Router script module. + */ +function wp_interactivity_router_script_module_data( array $data ): array { + return wp_interactivity()->filter_script_module_interactivity_router_data( $data ); +} + +/** + * Adds the `data-wp-router-options` attribute to script modules that support client-side navigation. + * + * @since 7.2.0 + * + * @see WP_Interactivity_API::add_load_on_client_navigation_attribute_to_script_modules() + * + * @param array|mixed $attributes The script tag attributes. + * @return array The modified script tag attributes. + */ +function wp_interactivity_script_module_attributes( $attributes ) { + return wp_interactivity()->add_load_on_client_navigation_attribute_to_script_modules( $attributes ); +} + +/** + * Outputs markup for the `@wordpress/interactivity-router` script module. + * + * @since 7.2.0 + * + * @see WP_Interactivity_API::print_router_markup() + */ +function wp_interactivity_print_router_markup(): void { + wp_interactivity()->print_router_markup(); +} diff --git a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php index 9d5a4024fc6c9..21ff26a787bd2 100644 --- a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php +++ b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php @@ -19,12 +19,28 @@ class Tests_Interactivity_API_WpInteractivityAPI extends WP_UnitTestCase { */ protected $interactivity; + /** + * Original global WP_Interactivity_API instance. + * + * @var WP_Interactivity_API|null + */ + protected $original_wp_interactivity; + /** * Set up. */ public function set_up() { + global $wp_interactivity; parent::set_up(); $this->interactivity = new WP_Interactivity_API(); + + /* + * The hooks added by `add_hooks()` operate on the global instance, so the + * test instance must be the global one for those hooks to see its data. + */ + $this->original_wp_interactivity = $wp_interactivity; + $wp_interactivity = $this->interactivity; + wp_default_script_modules(); $this->interactivity->add_hooks(); } @@ -33,9 +49,10 @@ public function set_up() { * Tear down. */ public function tear_down() { - global $wp_script_modules; + global $wp_script_modules, $wp_interactivity; parent::tear_down(); $wp_script_modules = null; + $wp_interactivity = $this->original_wp_interactivity; } public function charset_iso_8859_1() { @@ -2363,4 +2380,27 @@ public function test_add_client_navigation_support_to_script_module() { $this->assertSame( 'unmarked-module-js-module', $p->get_attribute( 'id' ) ); $this->assertNull( $p->get_attribute( 'data-wp-router-options' ) ); } + + /** + * Tests that the callbacks added by `add_hooks()` read the current global + * WP_Interactivity_API instance when they run. + * + * @ticket 66100 + * @covers WP_Interactivity_API::add_hooks + */ + public function test_add_hooks_callbacks_read_the_current_global_instance() { + global $wp_interactivity; + + // set_up() registered the hooks on the instance that is the global. + $wp_interactivity = new WP_Interactivity_API(); + wp_interactivity_state( 'test-hooks-global', array( 'value' => 'from-current-global' ) ); + + $data = apply_filters( 'script_module_data_@wordpress/interactivity', array() ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores + + $this->assertSame( + array( 'state' => array( 'test-hooks-global' => array( 'value' => 'from-current-global' ) ) ), + $data, + 'The filter callbacks added by add_hooks() must read the current global WP_Interactivity_API instance.' + ); + } }