Make WordPress Core

Changeset 58870


Ignore:
Timestamp:
08/08/2024 04:13:25 PM (2 years ago)
Author:
dmsnell
Message:

HTML API: expect_closer() should report false for self-closing foreign elements.

Previously, WP_HTML_Processor::expects_closer() would report true for self-closing foreign elements when called without supplying a node in question, but it should have been reporting true just as it does for HTML elements.

This patch adds a test case demonstrating the issue and a bugfix.

The html5lib test runner was relying on the incorrect behavior, accidentally working. This is also corrected and the html5lib test now relies on the correct behavior of expects_closer().

Developed in https://github.com/wordpress/wordpress-develop/pull/7162
Discussed in https://core.trac.wordpress.org/ticket/61576

Follow-up to [58868].

Props: dmsnell.
See #61576.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/html-api/class-wp-html-processor.php

    r58867 r58870  
    787787         */
    788788        public function expects_closer( WP_HTML_Token $node = null ): ?bool {
    789                 $token_name      = $node->node_name ?? $this->get_token_name();
    790                 $token_namespace = $node->namespace ?? $this->get_namespace();
     789                $token_name = $node->node_name ?? $this->get_token_name();
    791790
    792791                if ( ! isset( $token_name ) ) {
    793792                        return null;
    794793                }
     794
     795                $token_namespace        = $node->namespace ?? $this->get_namespace();
     796                $token_has_self_closing = $node->has_self_closing_flag ?? $this->has_self_closing_flag();
    795797
    796798                return ! (
     
    804806                        ( 'html' === $token_namespace && in_array( $token_name, array( 'IFRAME', 'NOEMBED', 'NOFRAMES', 'SCRIPT', 'STYLE', 'TEXTAREA', 'TITLE', 'XMP' ), true ) ) ||
    805807                        // Self-closing elements in foreign content.
    806                         ( isset( $node ) && 'html' !== $node->namespace && $node->has_self_closing_flag )
     808                        ( 'html' !== $token_namespace && $token_has_self_closing )
    807809                );
    808810        }
  • trunk/src/wp-includes/html-api/class-wp-html-tag-processor.php

    r58867 r58870  
    29222922                }
    29232923
    2924                 $namespace = $this->get_namespace();
     2924                $namespace  = $this->get_namespace();
    29252925                $lower_name = strtolower( $attribute_name );
    29262926
  • trunk/tests/phpunit/tests/html-api/wpHtmlProcessor.php

    r58867 r58870  
    504504                $this->assertInstanceOf( get_class( $subclass_instance ), $subclass_processor, '::create_fragment did not return subclass instance.' );
    505505        }
     506
     507        /**
     508         * Ensures that self-closing elements in foreign content properly report
     509         * that they expect no closer.
     510         *
     511         * @ticket 61576
     512         */
     513        public function test_expects_closer_foreign_content_self_closing() {
     514                $processor = WP_HTML_Processor::create_fragment( '<svg /><math>' );
     515
     516                $this->assertTrue( $processor->next_tag() );
     517                $this->assertSame( 'SVG', $processor->get_tag() );
     518                $this->assertFalse( $processor->expects_closer() );
     519
     520                $this->assertTrue( $processor->next_tag() );
     521                $this->assertSame( 'MATH', $processor->get_tag() );
     522                $this->assertTrue( $processor->expects_closer() );
     523        }
    506524}
  • trunk/tests/phpunit/tests/html-api/wpHtmlProcessorHtml5lib.php

    r58867 r58870  
    208208                                        $tag_indent = $indent_level;
    209209
    210                                         if ( 'html' !== $namespace ) {
    211                                                 if ( ! $processor->has_self_closing_flag() ) {
    212                                                         ++$indent_level;
    213                                                 }
    214                                         } elseif ( ! WP_HTML_Processor::is_void( $tag_name ) ) {
     210                                        if ( $processor->expects_closer() ) {
    215211                                                ++$indent_level;
    216212                                        }
     
    276272                                        $modifiable_text = $processor->get_modifiable_text();
    277273                                        if ( '' !== $modifiable_text ) {
    278                                                 $output .= str_repeat( $indent, $indent_level ) . "\"{$modifiable_text}\"\n";
     274                                                $output .= str_repeat( $indent, $tag_indent + 1 ) . "\"{$modifiable_text}\"\n";
    279275                                        }
    280276
     
    282278                                                $output .= str_repeat( $indent, $indent_level ) . "content\n";
    283279                                                ++$indent_level;
    284                                         }
    285 
    286                                         if ( ! $processor->is_void( $tag_name ) && ! $processor->expects_closer() ) {
    287                                                 --$indent_level;
    288280                                        }
    289281
Note: See TracChangeset for help on using the changeset viewer.