Make WordPress Core


Ignore:
Timestamp:
11/17/2023 06:11:31 AM (17 months ago)
Author:
Bernhard Reiter
Message:

HTML API: Add support for containers elements, including ARTICLE.

There are a handful of elements which behave similarly and are generically container elements. These are the following elements:

ADDRESS, ARTICLE, ASIDE, BLOCKQUOTE, CENTER, DETAILS, DIALOG, DIR,
DL, DIV, FIELDSET, FIGCAPTION, FIGURE, FOOTER, HEADER, HGROUP, MAIN,
MENU, NAV, SEARCH, SECTION, SUMMARY

This patch adds support to the HTML Processor for handling these elements. They do not require any additional logic in the rest of the class, and carry no specific semantic rules for parsing beyond what is listed in their group in the IN BODY section of the HTML5 specification.

Props dmsnell.
Fixes #59914.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/html-api/wpHtmlProcessorSemanticRules.php

    r56790 r57115  
    1818
    1919    /**
     20     * Verifies that tags in the container group, including the ARTICLE element,
     21     * close out an open P element if one exists.
     22     *
     23     * @covers WP_HTML_Processor::step_in_body
     24     *
     25     * @ticket 59914
     26     *
     27     * @dataProvider data_article_container_group
     28     *
     29     * @param string $tag_name Name of tag in group under test.
     30     */
     31    public function test_in_body_article_group_closes_open_p_element( $tag_name ) {
     32        $processor = WP_HTML_Processor::create_fragment( "<p><p><p><p><{$tag_name} target>" );
     33
     34        while ( $processor->next_tag() && null === $processor->get_attribute( 'target' ) ) {
     35            continue;
     36        }
     37
     38        $this->assertEquals(
     39            $tag_name,
     40            $processor->get_tag(),
     41            "Expected to find {$tag_name} but found {$processor->get_tag()} instead."
     42        );
     43
     44        $this->assertSame(
     45            array( 'HTML', 'BODY', $tag_name ),
     46            $processor->get_breadcrumbs(),
     47            "Expected to find {$tag_name} as direct child of BODY as a result of implicitly closing an open P element."
     48        );
     49    }
     50
     51    /**
     52     * Verifies that tags in the container group, including the ARTICLE element,
     53     * nest inside each other despite being invalid in most cases.
     54     *
     55     * @covers WP_HTML_Processor::step_in_body
     56     *
     57     * @ticket 59914
     58     *
     59     * @dataProvider data_article_container_group
     60     *
     61     * @param string $tag_name Name of tag in group under test.
     62     */
     63    public function test_in_body_article_group_can_nest_inside_itself( $tag_name ) {
     64        $processor = WP_HTML_Processor::create_fragment( "<div><{$tag_name}><{$tag_name}></{$tag_name}><{$tag_name}><span><{$tag_name} target>" );
     65
     66        while ( $processor->next_tag() && null === $processor->get_attribute( 'target' ) ) {
     67            continue;
     68        }
     69
     70        $this->assertSame(
     71            array( 'HTML', 'BODY', 'DIV', $tag_name, $tag_name, 'SPAN', $tag_name ),
     72            $processor->get_breadcrumbs(),
     73            "Expected to find {$tag_name} deeply nested inside itself."
     74        );
     75    }
     76
     77    /**
     78     * Data provider.
     79     *
     80     * @return array[].
     81     */
     82    public function data_article_container_group() {
     83        $group = array();
     84
     85        foreach (
     86            array(
     87                'ADDRESS',
     88                'ARTICLE',
     89                'ASIDE',
     90                'BLOCKQUOTE',
     91                'CENTER',
     92                'DETAILS',
     93                'DIALOG',
     94                'DIR',
     95                'DL',
     96                'DIV',
     97                'FIELDSET',
     98                'FIGCAPTION',
     99                'FIGURE',
     100                'FOOTER',
     101                'HEADER',
     102                'HGROUP',
     103                'MAIN',
     104                'MENU',
     105                'NAV',
     106                'SEARCH',
     107                'SECTION',
     108                'SUMMARY',
     109            )
     110            as $tag_name
     111        ) {
     112            $group[ $tag_name ] = array( $tag_name );
     113        }
     114
     115        return $group;
     116    }
     117
     118    /**
    20119     * Verifies that when encountering an end tag for which there is no corresponding
    21120     * element in scope, that it skips the tag entirely.
     
    143242     * element on the stack of open elements before the matching opening.
    144243     *
     244     * @covers WP_HTML_Processor::step_in_body
     245     *
    145246     * @ticket 58907
    146247     *
    147248     * @since 6.4.0
    148      *
    149      * @covers WP_HTML_Processor::step_in_body
    150249     */
    151250    public function test_in_body_any_other_end_tag_with_unclosed_special_element() {
     
    166265     * open elements up to the matching opening.
    167266     *
     267     * @covers WP_HTML_Processor::step_in_body
     268     *
    168269     * @ticket 58907
    169270     *
    170271     * @since 6.4.0
    171      *
    172      * @covers WP_HTML_Processor::step_in_body
    173272     */
    174273    public function test_in_body_any_other_end_tag_with_unclosed_non_special_element() {
Note: See TracChangeset for help on using the changeset viewer.