Make WordPress Core

Changeset 58870


Ignore:
Timestamp:
08/08/2024 04:13:25 PM (8 months 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.