diff --git a/lib/experimental/interactivity-api/directives/wp-context.php b/lib/experimental/interactivity-api/directives/wp-context.php
index bf3014c5772d7..7d92b0ac7b0c6 100644
--- a/lib/experimental/interactivity-api/directives/wp-context.php
+++ b/lib/experimental/interactivity-api/directives/wp-context.php
@@ -18,16 +18,11 @@ function gutenberg_interactivity_process_wp_context( $tags, $context ) {
}
$value = $tags->get_attribute( 'data-wp-context' );
- if ( null === $value ) {
- // No data-wp-context directive.
- return;
- }
- $new_context = json_decode( $value, true );
- if ( null === $new_context ) {
- // If the JSON is not valid, we still add an empty array to the stack.
- $new_context = array();
- }
+ $new_context = json_decode(
+ is_string( $value ) && ! empty( $value ) ? $value : '{}',
+ true
+ );
- $context->set_context( $new_context );
+ $context->set_context( $new_context ?? array() );
}
diff --git a/phpunit/experimental/interactivity-api/directives/wp-context-test.php b/phpunit/experimental/interactivity-api/directives/wp-context-test.php
index d3f44a5e4fd81..1277b016848cc 100644
--- a/phpunit/experimental/interactivity-api/directives/wp-context-test.php
+++ b/phpunit/experimental/interactivity-api/directives/wp-context-test.php
@@ -124,4 +124,106 @@ public function test_directive_keeps_working_after_malformed_context_objects() {
$context->get_context()
);
}
+
+ public function test_directive_keeps_working_with_a_directive_without_value() {
+ $context = new WP_Directive_Context();
+
+ $markup = '
+
+ ';
+ $tags = new WP_HTML_Tag_Processor( $markup );
+
+ // Parent div.
+ $tags->next_tag( array( 'tag_closers' => 'visit' ) );
+ gutenberg_interactivity_process_wp_context( $tags, $context );
+
+ $this->assertSame(
+ array( 'my-key' => 'some-value' ),
+ $context->get_context()
+ );
+
+ // Children div.
+ $tags->next_tag( array( 'tag_closers' => 'visit' ) );
+ gutenberg_interactivity_process_wp_context( $tags, $context );
+
+ // Still the same context.
+ $this->assertSame(
+ array( 'my-key' => 'some-value' ),
+ $context->get_context()
+ );
+
+ // Closing children div.
+ $tags->next_tag( array( 'tag_closers' => 'visit' ) );
+ gutenberg_interactivity_process_wp_context( $tags, $context );
+
+ // Still the same context.
+ $this->assertSame(
+ array( 'my-key' => 'some-value' ),
+ $context->get_context()
+ );
+
+ // Closing parent div.
+ $tags->next_tag( array( 'tag_closers' => 'visit' ) );
+ gutenberg_interactivity_process_wp_context( $tags, $context );
+
+ // Now the context is empty.
+ $this->assertSame(
+ array(),
+ $context->get_context()
+ );
+ }
+
+ public function test_directive_keeps_working_with_an_empty_directive() {
+ $context = new WP_Directive_Context();
+
+ $markup = '
+
+ ';
+ $tags = new WP_HTML_Tag_Processor( $markup );
+
+ // Parent div.
+ $tags->next_tag( array( 'tag_closers' => 'visit' ) );
+ gutenberg_interactivity_process_wp_context( $tags, $context );
+
+ $this->assertSame(
+ array( 'my-key' => 'some-value' ),
+ $context->get_context()
+ );
+
+ // Children div.
+ $tags->next_tag( array( 'tag_closers' => 'visit' ) );
+ gutenberg_interactivity_process_wp_context( $tags, $context );
+
+ // Still the same context.
+ $this->assertSame(
+ array( 'my-key' => 'some-value' ),
+ $context->get_context()
+ );
+
+ // Closing children div.
+ $tags->next_tag( array( 'tag_closers' => 'visit' ) );
+ gutenberg_interactivity_process_wp_context( $tags, $context );
+
+ // Still the same context.
+ $this->assertSame(
+ array( 'my-key' => 'some-value' ),
+ $context->get_context()
+ );
+
+ // Closing parent div.
+ $tags->next_tag( array( 'tag_closers' => 'visit' ) );
+ gutenberg_interactivity_process_wp_context( $tags, $context );
+
+ // Now the context is empty.
+ $this->assertSame(
+ array(),
+ $context->get_context()
+ );
+ }
}