Make WordPress Core


Ignore:
Timestamp:
10/23/2024 10:03:23 PM (7 months ago)
Author:
westonruter
Message:

HTML API: Fix extensibility of WP_HTML_Processor::next_token().

Break out logic from the next_token() method into a private method which may call itself recursively. This allows for subclasses to override the next_token() method and be assured that each call to next_token() corresponds with the consumption of one single token. This also parallels how WP_HTML_Tag_Processor::next_token() wraps a private base_class_next_token() method.

Props westonruter, jonsurrell.
Fixes #62269.

File:
1 edited

Legend:

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

    r59248 r59285  
    883883        $this->assertTrue( $processor->is_tag_closer() );
    884884    }
     885
     886    /**
     887     * Data provider.
     888     *
     889     * @return array
     890     */
     891    public function data_html_processor_with_extended_next_token() {
     892        return array(
     893            'single_instance_per_tag'   => array(
     894                'html'                  => '
     895                    <html>
     896                        <head>
     897                            <meta charset="utf-8">
     898                            <title>Hello World</title>
     899                        </head>
     900                        <body>
     901                            <h1>Hello World!</h1>
     902                            <img src="example.png">
     903                            <p>Each tag should occur only once in this document.<!--Closing P tag omitted intentionally.-->
     904                            <footer>The end.</footer>
     905                        </body>
     906                    </html>
     907                ',
     908                'expected_token_counts' => array(
     909                    '+HTML'    => 1,
     910                    '+HEAD'    => 1,
     911                    '#text'    => 14,
     912                    '+META'    => 1,
     913                    '+TITLE'   => 1,
     914                    '-HEAD'    => 1,
     915                    '+BODY'    => 1,
     916                    '+H1'      => 1,
     917                    '-H1'      => 1,
     918                    '+IMG'     => 1,
     919                    '+P'       => 1,
     920                    '#comment' => 1,
     921                    '-P'       => 1,
     922                    '+FOOTER'  => 1,
     923                    '-FOOTER'  => 1,
     924                    '-BODY'    => 1,
     925                    '-HTML'    => 1,
     926                    ''         => 1,
     927                ),
     928                'expected_xpaths'       => array(
     929                    0 => '/*[1][self::HTML]',
     930                    1 => '/*[1][self::HTML]/*[1][self::HEAD]',
     931                    2 => '/*[1][self::HTML]/*[1][self::HEAD]/*[1][self::META]',
     932                    3 => '/*[1][self::HTML]/*[1][self::HEAD]/*[2][self::TITLE]',
     933                    4 => '/*[1][self::HTML]/*[2][self::BODY]',
     934                    5 => '/*[1][self::HTML]/*[2][self::BODY]/*[1][self::H1]',
     935                    6 => '/*[1][self::HTML]/*[2][self::BODY]/*[2][self::IMG]',
     936                    7 => '/*[1][self::HTML]/*[2][self::BODY]/*[3][self::P]',
     937                    8 => '/*[1][self::HTML]/*[2][self::BODY]/*[4][self::FOOTER]',
     938                ),
     939            ),
     940
     941            'multiple_tag_instances'    => array(
     942                'html'                  => '
     943                    <html>
     944                        <body>
     945                            <h1>Hello World!</h1>
     946                            <p>First
     947                            <p>Second
     948                            <p>Third
     949                            <ul>
     950                                <li>1
     951                                <li>2
     952                                <li>3
     953                            </ul>
     954                        </body>
     955                    </html>
     956                ',
     957                'expected_token_counts' => array(
     958                    '+HTML' => 1,
     959                    '+HEAD' => 1,
     960                    '-HEAD' => 1,
     961                    '+BODY' => 1,
     962                    '#text' => 13,
     963                    '+H1'   => 1,
     964                    '-H1'   => 1,
     965                    '+P'    => 3,
     966                    '-P'    => 3,
     967                    '+UL'   => 1,
     968                    '+LI'   => 3,
     969                    '-LI'   => 3,
     970                    '-UL'   => 1,
     971                    '-BODY' => 1,
     972                    '-HTML' => 1,
     973                    ''      => 1,
     974                ),
     975                'expected_xpaths'       => array(
     976                    0  => '/*[1][self::HTML]',
     977                    1  => '/*[1][self::HTML]/*[1][self::HEAD]',
     978                    2  => '/*[1][self::HTML]/*[2][self::BODY]',
     979                    3  => '/*[1][self::HTML]/*[2][self::BODY]/*[1][self::H1]',
     980                    4  => '/*[1][self::HTML]/*[2][self::BODY]/*[2][self::P]',
     981                    5  => '/*[1][self::HTML]/*[2][self::BODY]/*[3][self::P]',
     982                    6  => '/*[1][self::HTML]/*[2][self::BODY]/*[4][self::P]',
     983                    7  => '/*[1][self::HTML]/*[2][self::BODY]/*[5][self::UL]',
     984                    8  => '/*[1][self::HTML]/*[2][self::BODY]/*[5][self::UL]/*[1][self::LI]',
     985                    9  => '/*[1][self::HTML]/*[2][self::BODY]/*[5][self::UL]/*[2][self::LI]',
     986                    10 => '/*[1][self::HTML]/*[2][self::BODY]/*[5][self::UL]/*[3][self::LI]',
     987                ),
     988            ),
     989
     990            'extreme_nested_formatting' => array(
     991                'html'                  => '
     992                    <html>
     993                        <body>
     994                            <p>
     995                                <strong><em><strike><i><b><u>FORMAT</u></b></i></strike></em></strong>
     996                            </p>
     997                        </body>
     998                    </html>
     999                ',
     1000                'expected_token_counts' => array(
     1001                    '+HTML'   => 1,
     1002                    '+HEAD'   => 1,
     1003                    '-HEAD'   => 1,
     1004                    '+BODY'   => 1,
     1005                    '#text'   => 7,
     1006                    '+P'      => 1,
     1007                    '+STRONG' => 1,
     1008                    '+EM'     => 1,
     1009                    '+STRIKE' => 1,
     1010                    '+I'      => 1,
     1011                    '+B'      => 1,
     1012                    '+U'      => 1,
     1013                    '-U'      => 1,
     1014                    '-B'      => 1,
     1015                    '-I'      => 1,
     1016                    '-STRIKE' => 1,
     1017                    '-EM'     => 1,
     1018                    '-STRONG' => 1,
     1019                    '-P'      => 1,
     1020                    '-BODY'   => 1,
     1021                    '-HTML'   => 1,
     1022                    ''        => 1,
     1023                ),
     1024                'expected_xpaths'       => array(
     1025                    0 => '/*[1][self::HTML]',
     1026                    1 => '/*[1][self::HTML]/*[1][self::HEAD]',
     1027                    2 => '/*[1][self::HTML]/*[2][self::BODY]',
     1028                    3 => '/*[1][self::HTML]/*[2][self::BODY]/*[1][self::P]',
     1029                    4 => '/*[1][self::HTML]/*[2][self::BODY]/*[1][self::P]/*[1][self::STRONG]',
     1030                    5 => '/*[1][self::HTML]/*[2][self::BODY]/*[1][self::P]/*[1][self::STRONG]/*[1][self::EM]',
     1031                    6 => '/*[1][self::HTML]/*[2][self::BODY]/*[1][self::P]/*[1][self::STRONG]/*[1][self::EM]/*[1][self::STRIKE]',
     1032                    7 => '/*[1][self::HTML]/*[2][self::BODY]/*[1][self::P]/*[1][self::STRONG]/*[1][self::EM]/*[1][self::STRIKE]/*[1][self::I]',
     1033                    8 => '/*[1][self::HTML]/*[2][self::BODY]/*[1][self::P]/*[1][self::STRONG]/*[1][self::EM]/*[1][self::STRIKE]/*[1][self::I]/*[1][self::B]',
     1034                    9 => '/*[1][self::HTML]/*[2][self::BODY]/*[1][self::P]/*[1][self::STRONG]/*[1][self::EM]/*[1][self::STRIKE]/*[1][self::I]/*[1][self::B]/*[1][self::U]',
     1035                ),
     1036            ),
     1037        );
     1038    }
     1039
     1040    /**
     1041     * Ensures that subclasses to WP_HTML_Processor can do bookkeeping by extending the next_token() method.
     1042     *
     1043     * @ticket ?
     1044     * @dataProvider data_html_processor_with_extended_next_token
     1045     */
     1046    public function test_ensure_next_token_method_extensibility( $html, $expected_token_counts, $expected_xpaths ) {
     1047        require_once DIR_TESTDATA . '/html-api/html-xpath-generating-processor.php';
     1048
     1049        $processor     = HTML_XPath_Generating_Processor::create_full_parser( $html );
     1050        $actual_xpaths = array();
     1051        while ( $processor->next_tag() ) {
     1052            if ( ! $processor->is_tag_closer() ) {
     1053                $processor->set_attribute( 'xpath', $processor->get_xpath() );
     1054                $actual_xpaths[] = $processor->get_xpath();
     1055            }
     1056        }
     1057
     1058        $this->assertEquals( $expected_token_counts, $processor->token_seen_count, 'Snapshot: ' . var_export( $processor->token_seen_count, true ) );
     1059        $this->assertEquals( $expected_xpaths, $actual_xpaths, 'Snapshot: ' . var_export( $actual_xpaths, true ) );
     1060    }
    8851061}
Note: See TracChangeset for help on using the changeset viewer.