Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/interactivity-api/class-wp-interactivity-api.php
r57824 r57832 295 295 } 296 296 /* 297 298 299 297 * If the matching opener tag didn't have any directives, it can skip the 298 * processing. 299 */ 300 300 if ( 0 === count( $directives_prefixes ) ) { 301 301 continue; 302 302 } 303 303 304 /* 305 * Sorts the attributes by the order of the `directives_processor` array 306 * and checks what directives are present in this element. The processing 307 * order is reversed for tag closers. 308 */ 309 $directives_prefixes = array_intersect( 310 $p->is_tag_closer() 311 ? $directive_processor_prefixes_reversed 312 : $directive_processor_prefixes, 313 $directives_prefixes 304 // Directive processing might be different depending on if it is entering the tag or exiting it. 305 $modes = array( 306 'enter' => ! $p->is_tag_closer(), 307 'exit' => $p->is_tag_closer() || ! $p->has_and_visits_its_closer_tag(), 314 308 ); 315 309 316 // Executes the directive processors present in this element. 317 foreach ( $directives_prefixes as $directive_prefix ) { 318 $func = is_array( self::$directive_processors[ $directive_prefix ] ) 319 ? self::$directive_processors[ $directive_prefix ] 320 : array( $this, self::$directive_processors[ $directive_prefix ] ); 321 call_user_func_array( 322 $func, 323 array( $p, &$context_stack, &$namespace_stack, &$tag_stack ) 310 foreach ( $modes as $mode => $should_run ) { 311 if ( ! $should_run ) { 312 continue; 313 } 314 315 /* 316 * Sorts the attributes by the order of the `directives_processor` array 317 * and checks what directives are present in this element. 318 */ 319 $existing_directives_prefixes = array_intersect( 320 'enter' === $mode ? $directive_processor_prefixes : $directive_processor_prefixes_reversed, 321 $directives_prefixes 324 322 ); 323 foreach ( $existing_directives_prefixes as $directive_prefix ) { 324 $func = is_array( self::$directive_processors[ $directive_prefix ] ) 325 ? self::$directive_processors[ $directive_prefix ] 326 : array( $this, self::$directive_processors[ $directive_prefix ] ); 327 328 call_user_func_array( 329 $func, 330 array( $p, $mode, &$context_stack, &$namespace_stack, &$tag_stack ) 331 ); 332 } 325 333 } 326 334 } … … 475 483 * 476 484 * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. 485 * @param string $mode Whether the processing is entering or exiting the tag. 477 486 * @param array $context_stack The reference to the context stack. 478 487 * @param array $namespace_stack The reference to the store namespace stack. 479 488 */ 480 private function data_wp_interactive_processor( WP_Interactivity_API_Directives_Processor $p, array &$context_stack, array &$namespace_stack ) {481 // In closing tags, it removes the last namespace from the stack.482 if ( $p->is_tag_closer()) {489 private function data_wp_interactive_processor( WP_Interactivity_API_Directives_Processor $p, string $mode, array &$context_stack, array &$namespace_stack ) { 490 // When exiting tags, it removes the last namespace from the stack. 491 if ( 'exit' === $mode ) { 483 492 array_pop( $namespace_stack ); 484 493 return; … … 519 528 * 520 529 * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. 530 * @param string $mode Whether the processing is entering or exiting the tag. 521 531 * @param array $context_stack The reference to the context stack. 522 532 * @param array $namespace_stack The reference to the store namespace stack. 523 533 */ 524 private function data_wp_context_processor( WP_Interactivity_API_Directives_Processor $p, array &$context_stack, array &$namespace_stack ) {525 // In closing tags, it removes the last context from the stack.526 if ( $p->is_tag_closer()) {534 private function data_wp_context_processor( WP_Interactivity_API_Directives_Processor $p, string $mode, array &$context_stack, array &$namespace_stack ) { 535 // When exiting tags, it removes the last context from the stack. 536 if ( 'exit' === $mode ) { 527 537 array_pop( $context_stack ); 528 538 return; … … 565 575 * 566 576 * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. 577 * @param string $mode Whether the processing is entering or exiting the tag. 567 578 * @param array $context_stack The reference to the context stack. 568 579 * @param array $namespace_stack The reference to the store namespace stack. 569 580 */ 570 private function data_wp_bind_processor( WP_Interactivity_API_Directives_Processor $p, array &$context_stack, array &$namespace_stack ) {571 if ( ! $p->is_tag_closer()) {581 private function data_wp_bind_processor( WP_Interactivity_API_Directives_Processor $p, string $mode, array &$context_stack, array &$namespace_stack ) { 582 if ( 'enter' === $mode ) { 572 583 $all_bind_directives = $p->get_attribute_names_with_prefix( 'data-wp-bind--' ); 573 584 … … 609 620 * 610 621 * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. 622 * @param string $mode Whether the processing is entering or exiting the tag. 611 623 * @param array $context_stack The reference to the context stack. 612 624 * @param array $namespace_stack The reference to the store namespace stack. 613 625 */ 614 private function data_wp_class_processor( WP_Interactivity_API_Directives_Processor $p, array &$context_stack, array &$namespace_stack ) {615 if ( ! $p->is_tag_closer()) {626 private function data_wp_class_processor( WP_Interactivity_API_Directives_Processor $p, string $mode, array &$context_stack, array &$namespace_stack ) { 627 if ( 'enter' === $mode ) { 616 628 $all_class_directives = $p->get_attribute_names_with_prefix( 'data-wp-class--' ); 617 629 … … 643 655 * 644 656 * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. 657 * @param string $mode Whether the processing is entering or exiting the tag. 645 658 * @param array $context_stack The reference to the context stack. 646 659 * @param array $namespace_stack The reference to the store namespace stack. 647 660 */ 648 private function data_wp_style_processor( WP_Interactivity_API_Directives_Processor $p, array &$context_stack, array &$namespace_stack ) {649 if ( ! $p->is_tag_closer()) {661 private function data_wp_style_processor( WP_Interactivity_API_Directives_Processor $p, string $mode, array &$context_stack, array &$namespace_stack ) { 662 if ( 'enter' === $mode ) { 650 663 $all_style_attributes = $p->get_attribute_names_with_prefix( 'data-wp-style--' ); 651 664 … … 735 748 * 736 749 * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. 750 * @param string $mode Whether the processing is entering or exiting the tag. 737 751 * @param array $context_stack The reference to the context stack. 738 752 * @param array $namespace_stack The reference to the store namespace stack. 739 753 */ 740 private function data_wp_text_processor( WP_Interactivity_API_Directives_Processor $p, array &$context_stack, array &$namespace_stack ) {741 if ( ! $p->is_tag_closer()) {754 private function data_wp_text_processor( WP_Interactivity_API_Directives_Processor $p, string $mode, array &$context_stack, array &$namespace_stack ) { 755 if ( 'enter' === $mode ) { 742 756 $attribute_value = $p->get_attribute( 'data-wp-text' ); 743 757 $result = $this->evaluate( $attribute_value, end( $namespace_stack ), end( $context_stack ) ); … … 832 846 * @since 6.5.0 833 847 * 834 * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. 835 */ 836 private function data_wp_router_region_processor( WP_Interactivity_API_Directives_Processor $p ) { 837 if ( ! $p->is_tag_closer() && ! $this->has_processed_router_region ) { 848 * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. 849 * @param string $mode Whether the processing is entering or exiting the tag. 850 */ 851 private function data_wp_router_region_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ) { 852 if ( 'enter' === $mode && ! $this->has_processed_router_region ) { 838 853 $this->has_processed_router_region = true; 839 854 … … 871 886 * 872 887 * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. 888 * @param string $mode Whether the processing is entering or exiting the tag. 873 889 * @param array $context_stack The reference to the context stack. 874 890 * @param array $namespace_stack The reference to the store namespace stack. 875 891 * @param array $tag_stack The reference to the tag stack. 876 892 */ 877 private function data_wp_each_processor( WP_Interactivity_API_Directives_Processor $p, array &$context_stack, array &$namespace_stack, array &$tag_stack ) {878 if ( ! $p->is_tag_closer()&& 'TEMPLATE' === $p->get_tag() ) {893 private function data_wp_each_processor( WP_Interactivity_API_Directives_Processor $p, string $mode, array &$context_stack, array &$namespace_stack, array &$tag_stack ) { 894 if ( 'enter' === $mode && 'TEMPLATE' === $p->get_tag() ) { 879 895 $attribute_name = $p->get_attribute_names_with_prefix( 'data-wp-each' )[0]; 880 896 $extracted_suffix = $this->extract_prefix_and_suffix( $attribute_name ); -
trunk/tests/phpunit/tests/interactivity-api/wpInteractivityAPIFunctions.php
r57826 r57832 451 451 $this->assertEquals( '1', $processor->get_attribute( 'src' ) ); 452 452 } 453 454 /** 455 * Tests that context from void tags is not propagated to next tags. 456 * 457 * @ticket 60768 458 * 459 * @covers wp_interactivity_process_directives_of_interactive_blocks 460 */ 461 public function test_process_context_directive_in_void_tags() { 462 register_block_type( 463 'test/custom-directive-block', 464 array( 465 'render_callback' => function () { 466 return '<div data-wp-interactive="nameSpace" data-wp-context=\'{"text": "outer"}\'><input id="first-input" data-wp-context=\'{"text": "inner"}\' data-wp-bind--value="context.text" /><input id="second-input" data-wp-bind--value="context.text" /></div>'; 467 }, 468 'supports' => array( 469 'interactivity' => true, 470 ), 471 ) 472 ); 473 $post_content = '<!-- wp:test/custom-directive-block /-->'; 474 $processed_content = do_blocks( $post_content ); 475 $processor = new WP_HTML_Tag_Processor( $processed_content ); 476 $processor->next_tag( 477 array( 478 'tag_name' => 'input', 479 'id' => 'first-input', 480 ) 481 ); 482 $first_input_value = $processor->get_attribute( 'value' ); 483 $processor->next_tag( 484 array( 485 'tag_name' => 'input', 486 'id' => 'second-input', 487 ) 488 ); 489 $second_input_value = $processor->get_attribute( 'value' ); 490 unregister_block_type( 'test/custom-directive-block' ); 491 $this->assertEquals( 'inner', $first_input_value ); 492 $this->assertEquals( 'outer', $second_input_value ); 493 } 494 495 /** 496 * Tests that namespace from void tags is not propagated to next tags. 497 * 498 * @ticket 60768 499 * 500 * @covers wp_interactivity_process_directives_of_interactive_blocks 501 */ 502 public function test_process_interactive_directive_in_void_tags() { 503 wp_interactivity_state( 504 'void', 505 array( 506 'text' => 'void', 507 ) 508 ); 509 register_block_type( 510 'test/custom-directive-block', 511 array( 512 'render_callback' => function () { 513 return '<div data-wp-interactive="parent"><img data-wp-interactive="void" /><input data-wp-bind--value="state.text" /></div>'; 514 }, 515 'supports' => array( 516 'interactivity' => true, 517 ), 518 ) 519 ); 520 $post_content = '<!-- wp:test/custom-directive-block /-->'; 521 $processed_content = do_blocks( $post_content ); 522 $processor = new WP_HTML_Tag_Processor( $processed_content ); 523 $processor->next_tag( array( 'tag_name' => 'input' ) ); 524 $input_value = $processor->get_attribute( 'value' ); 525 unregister_block_type( 'test/custom-directive-block' ); 526 $this->assertNull( $input_value ); 527 } 453 528 }
Note: See TracChangeset
for help on using the changeset viewer.