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() + ); + } }